Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. The Weird and The Wonderful
  4. personal worst...

personal worst...

Scheduled Pinned Locked Moved The Weird and The Wonderful
databasecsharphtmlasp-net
14 Posts 12 Posters 33 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D DerekT P

    Have just been asked to take over support for a live website. It's a mix of Classic ASP and ASP.Net. It runs on Windows Server 2003, .Net Framework 1.1, on a box running in the client's office. The business depends on the application. Because there's a mix of classic and .Net, and the login authentication is done in Classic with a login token stored in the Classic Session object, login status is inaccessible to the .Net pages. So you can just enter the URL of a .net page and you get full access to everything. Neat! The .ASPX pages are written exactly as Classic ASP; no code-behind, absolutely no separation of UI and business logic. HTML interspersed with VB.Net. Variables are defined without any type in most cases. There is no concept of objects and absolutely no code re-use (e.g. most pages can send emails, and there's all the code needed to setup an SMTP client on every page). Some pages connect to the database using ODBC and OLEDB concurrently, and the connection strings for each are hard-coded in the pages themselves. Came across this little snippet just now... The page has about 20 bound controls, dropdown lists, all setup the same way:

    mySelect = "select product_id, name from mytable"
    If Request.QueryString("cust_id") <> "0" Then
    mySelect = mySelect + " WHERE cust_id=" & Request.QueryString("cust_id")
    End If
    mySelect = mySelect + " order by name"
    myDBCommand = New OleDbCommand(mySelect, myConnection)
    myDBReader = myDBCommand.ExecuteReader()
    lstBox1.DataSource = myDBReader
    lstBox1.DataTextField = "name"
    lstBox1.DataValueField = "product_id"
    lstBox1.DataBind()
    myDBReader.Close()
    myDBReader = myDBCommand.ExecuteReader()
    iLoop = 0
    Do While myDBReader.Read And iLoop < 10000
    If product_id = myDBReader("product_id") Then '' (product_id is set previously)
    lstBox1.SelectedIndex = iLoop
    iLoop = 10000
    End If
    iLoop = iLoop + 1
    Loop
    myDBReader.Close()

    I don't know what I like least about this. The lack of validation of the querystring parameter; the concatenation of the query string into the SQL statement (ripe for SQL injection); the re-opening (i.e. re-execution) of the data reader; the looping through all the rows to match the existing value; the arbitrary limit of 10000 on the loop; the setting of the loop counter to 10000 rather than 9998 to exit the loop ... almost every line makes my head hurt. There's hundreds of pages written like this. Of which about 10% are actually used; the remainder are "old" versions of pages, but not n

    raddevusR Offline
    raddevusR Offline
    raddevus
    wrote on last edited by
    #2

    Sometimes code is the equivalent of a train wreck. What you have there is more like a jumbo jet crashing into the titanic which is sent hurtling into a train. :laugh: Well, thank goodness there are probably lots of global variables in there that will help you code this up right. :laugh: Good luck!

    1 Reply Last reply
    0
    • D DerekT P

      Have just been asked to take over support for a live website. It's a mix of Classic ASP and ASP.Net. It runs on Windows Server 2003, .Net Framework 1.1, on a box running in the client's office. The business depends on the application. Because there's a mix of classic and .Net, and the login authentication is done in Classic with a login token stored in the Classic Session object, login status is inaccessible to the .Net pages. So you can just enter the URL of a .net page and you get full access to everything. Neat! The .ASPX pages are written exactly as Classic ASP; no code-behind, absolutely no separation of UI and business logic. HTML interspersed with VB.Net. Variables are defined without any type in most cases. There is no concept of objects and absolutely no code re-use (e.g. most pages can send emails, and there's all the code needed to setup an SMTP client on every page). Some pages connect to the database using ODBC and OLEDB concurrently, and the connection strings for each are hard-coded in the pages themselves. Came across this little snippet just now... The page has about 20 bound controls, dropdown lists, all setup the same way:

      mySelect = "select product_id, name from mytable"
      If Request.QueryString("cust_id") <> "0" Then
      mySelect = mySelect + " WHERE cust_id=" & Request.QueryString("cust_id")
      End If
      mySelect = mySelect + " order by name"
      myDBCommand = New OleDbCommand(mySelect, myConnection)
      myDBReader = myDBCommand.ExecuteReader()
      lstBox1.DataSource = myDBReader
      lstBox1.DataTextField = "name"
      lstBox1.DataValueField = "product_id"
      lstBox1.DataBind()
      myDBReader.Close()
      myDBReader = myDBCommand.ExecuteReader()
      iLoop = 0
      Do While myDBReader.Read And iLoop < 10000
      If product_id = myDBReader("product_id") Then '' (product_id is set previously)
      lstBox1.SelectedIndex = iLoop
      iLoop = 10000
      End If
      iLoop = iLoop + 1
      Loop
      myDBReader.Close()

      I don't know what I like least about this. The lack of validation of the querystring parameter; the concatenation of the query string into the SQL statement (ripe for SQL injection); the re-opening (i.e. re-execution) of the data reader; the looping through all the rows to match the existing value; the arbitrary limit of 10000 on the loop; the setting of the loop counter to 10000 rather than 9998 to exit the loop ... almost every line makes my head hurt. There's hundreds of pages written like this. Of which about 10% are actually used; the remainder are "old" versions of pages, but not n

      R Offline
      R Offline
      RickZeeland
      wrote on last edited by
      #3

      I would recommend this approach: Computer treatment - YouTube[^] :-\

      C D Richard DeemingR 3 Replies Last reply
      0
      • D DerekT P

        Have just been asked to take over support for a live website. It's a mix of Classic ASP and ASP.Net. It runs on Windows Server 2003, .Net Framework 1.1, on a box running in the client's office. The business depends on the application. Because there's a mix of classic and .Net, and the login authentication is done in Classic with a login token stored in the Classic Session object, login status is inaccessible to the .Net pages. So you can just enter the URL of a .net page and you get full access to everything. Neat! The .ASPX pages are written exactly as Classic ASP; no code-behind, absolutely no separation of UI and business logic. HTML interspersed with VB.Net. Variables are defined without any type in most cases. There is no concept of objects and absolutely no code re-use (e.g. most pages can send emails, and there's all the code needed to setup an SMTP client on every page). Some pages connect to the database using ODBC and OLEDB concurrently, and the connection strings for each are hard-coded in the pages themselves. Came across this little snippet just now... The page has about 20 bound controls, dropdown lists, all setup the same way:

        mySelect = "select product_id, name from mytable"
        If Request.QueryString("cust_id") <> "0" Then
        mySelect = mySelect + " WHERE cust_id=" & Request.QueryString("cust_id")
        End If
        mySelect = mySelect + " order by name"
        myDBCommand = New OleDbCommand(mySelect, myConnection)
        myDBReader = myDBCommand.ExecuteReader()
        lstBox1.DataSource = myDBReader
        lstBox1.DataTextField = "name"
        lstBox1.DataValueField = "product_id"
        lstBox1.DataBind()
        myDBReader.Close()
        myDBReader = myDBCommand.ExecuteReader()
        iLoop = 0
        Do While myDBReader.Read And iLoop < 10000
        If product_id = myDBReader("product_id") Then '' (product_id is set previously)
        lstBox1.SelectedIndex = iLoop
        iLoop = 10000
        End If
        iLoop = iLoop + 1
        Loop
        myDBReader.Close()

        I don't know what I like least about this. The lack of validation of the querystring parameter; the concatenation of the query string into the SQL statement (ripe for SQL injection); the re-opening (i.e. re-execution) of the data reader; the looping through all the rows to match the existing value; the arbitrary limit of 10000 on the loop; the setting of the loop counter to 10000 rather than 9998 to exit the loop ... almost every line makes my head hurt. There's hundreds of pages written like this. Of which about 10% are actually used; the remainder are "old" versions of pages, but not n

        C Offline
        C Offline
        Chris Maunder
        wrote on last edited by
        #4

        :beer: You'll need it.

        cheers Chris Maunder

        1 Reply Last reply
        0
        • R RickZeeland

          I would recommend this approach: Computer treatment - YouTube[^] :-\

          C Offline
          C Offline
          charlieg
          wrote on last edited by
          #5

          smoke and a few pops? Suggest Office Space - Printer Scene (UNCENSORED) - YouTube[^] Now that scene was in California, so we could go to other extremes....

          Charlie Gilley <italic>Stuck in a dysfunctional matrix from which I must escape... "Where liberty dwells, there is my country." B. Franklin, 1783 “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759

          1 Reply Last reply
          0
          • R RickZeeland

            I would recommend this approach: Computer treatment - YouTube[^] :-\

            D Offline
            D Offline
            Daniel Pfeffer
            wrote on last edited by
            #6

            What a waste of good deodorant!

            Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

            R 1 Reply Last reply
            0
            • D DerekT P

              Have just been asked to take over support for a live website. It's a mix of Classic ASP and ASP.Net. It runs on Windows Server 2003, .Net Framework 1.1, on a box running in the client's office. The business depends on the application. Because there's a mix of classic and .Net, and the login authentication is done in Classic with a login token stored in the Classic Session object, login status is inaccessible to the .Net pages. So you can just enter the URL of a .net page and you get full access to everything. Neat! The .ASPX pages are written exactly as Classic ASP; no code-behind, absolutely no separation of UI and business logic. HTML interspersed with VB.Net. Variables are defined without any type in most cases. There is no concept of objects and absolutely no code re-use (e.g. most pages can send emails, and there's all the code needed to setup an SMTP client on every page). Some pages connect to the database using ODBC and OLEDB concurrently, and the connection strings for each are hard-coded in the pages themselves. Came across this little snippet just now... The page has about 20 bound controls, dropdown lists, all setup the same way:

              mySelect = "select product_id, name from mytable"
              If Request.QueryString("cust_id") <> "0" Then
              mySelect = mySelect + " WHERE cust_id=" & Request.QueryString("cust_id")
              End If
              mySelect = mySelect + " order by name"
              myDBCommand = New OleDbCommand(mySelect, myConnection)
              myDBReader = myDBCommand.ExecuteReader()
              lstBox1.DataSource = myDBReader
              lstBox1.DataTextField = "name"
              lstBox1.DataValueField = "product_id"
              lstBox1.DataBind()
              myDBReader.Close()
              myDBReader = myDBCommand.ExecuteReader()
              iLoop = 0
              Do While myDBReader.Read And iLoop < 10000
              If product_id = myDBReader("product_id") Then '' (product_id is set previously)
              lstBox1.SelectedIndex = iLoop
              iLoop = 10000
              End If
              iLoop = iLoop + 1
              Loop
              myDBReader.Close()

              I don't know what I like least about this. The lack of validation of the querystring parameter; the concatenation of the query string into the SQL statement (ripe for SQL injection); the re-opening (i.e. re-execution) of the data reader; the looping through all the rows to match the existing value; the arbitrary limit of 10000 on the loop; the setting of the loop counter to 10000 rather than 9998 to exit the loop ... almost every line makes my head hurt. There's hundreds of pages written like this. Of which about 10% are actually used; the remainder are "old" versions of pages, but not n

              G Offline
              G Offline
              GenJerDan
              wrote on last edited by
              #7

              Been there, done that, found a different job. ;)

              We won't sit down. We won't shut up. We won't go quietly away. YouTube, VidMe and My Mu[sic], Films and Windows Programs, etc. and FB

              1 Reply Last reply
              0
              • D Daniel Pfeffer

                What a waste of good deodorant!

                Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

                R Offline
                R Offline
                RickZeeland
                wrote on last edited by
                #8

                Bet you could use some (being the hard worker that you are :-\ )

                1 Reply Last reply
                0
                • R RickZeeland

                  I would recommend this approach: Computer treatment - YouTube[^] :-\

                  Richard DeemingR Offline
                  Richard DeemingR Offline
                  Richard Deeming
                  wrote on last edited by
                  #9

                  I say we take off and nuke the entire site from orbit. It's the only way to be sure. :-D


                  "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                  "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                  1 Reply Last reply
                  0
                  • D DerekT P

                    Have just been asked to take over support for a live website. It's a mix of Classic ASP and ASP.Net. It runs on Windows Server 2003, .Net Framework 1.1, on a box running in the client's office. The business depends on the application. Because there's a mix of classic and .Net, and the login authentication is done in Classic with a login token stored in the Classic Session object, login status is inaccessible to the .Net pages. So you can just enter the URL of a .net page and you get full access to everything. Neat! The .ASPX pages are written exactly as Classic ASP; no code-behind, absolutely no separation of UI and business logic. HTML interspersed with VB.Net. Variables are defined without any type in most cases. There is no concept of objects and absolutely no code re-use (e.g. most pages can send emails, and there's all the code needed to setup an SMTP client on every page). Some pages connect to the database using ODBC and OLEDB concurrently, and the connection strings for each are hard-coded in the pages themselves. Came across this little snippet just now... The page has about 20 bound controls, dropdown lists, all setup the same way:

                    mySelect = "select product_id, name from mytable"
                    If Request.QueryString("cust_id") <> "0" Then
                    mySelect = mySelect + " WHERE cust_id=" & Request.QueryString("cust_id")
                    End If
                    mySelect = mySelect + " order by name"
                    myDBCommand = New OleDbCommand(mySelect, myConnection)
                    myDBReader = myDBCommand.ExecuteReader()
                    lstBox1.DataSource = myDBReader
                    lstBox1.DataTextField = "name"
                    lstBox1.DataValueField = "product_id"
                    lstBox1.DataBind()
                    myDBReader.Close()
                    myDBReader = myDBCommand.ExecuteReader()
                    iLoop = 0
                    Do While myDBReader.Read And iLoop < 10000
                    If product_id = myDBReader("product_id") Then '' (product_id is set previously)
                    lstBox1.SelectedIndex = iLoop
                    iLoop = 10000
                    End If
                    iLoop = iLoop + 1
                    Loop
                    myDBReader.Close()

                    I don't know what I like least about this. The lack of validation of the querystring parameter; the concatenation of the query string into the SQL statement (ripe for SQL injection); the re-opening (i.e. re-execution) of the data reader; the looping through all the rows to match the existing value; the arbitrary limit of 10000 on the loop; the setting of the loop counter to 10000 rather than 9998 to exit the loop ... almost every line makes my head hurt. There's hundreds of pages written like this. Of which about 10% are actually used; the remainder are "old" versions of pages, but not n

                    H Offline
                    H Offline
                    Herman T Instance
                    wrote on last edited by
                    #10

                    Sounds like there is a big goodies bag at the end if you fix this!

                    In Word you can only store 2 bytes. That is why I use Writer.

                    D 1 Reply Last reply
                    0
                    • H Herman T Instance

                      Sounds like there is a big goodies bag at the end if you fix this!

                      In Word you can only store 2 bytes. That is why I use Writer.

                      D Offline
                      D Offline
                      DerekT P
                      wrote on last edited by
                      #11

                      If only. I quoted my (very cheap) hourly rate and the customer was obviously taken aback... "But I've been so used to paying £40/hour for years..." I used to charge clients £40/hour... in 1996. Peanuts and monkeys come to mind :-( Trouble is I like a challenge, am semi-retired so this is really like a paid hobby, and his offices are fabulous (an old English stately home, complete with wood panelling and huge portraits on the wall) so site visits are interesting! He has now agreed a rewrite is in order (once the initial fire fighting is over) so there's a good few months' work in it.

                      1 Reply Last reply
                      0
                      • D DerekT P

                        Have just been asked to take over support for a live website. It's a mix of Classic ASP and ASP.Net. It runs on Windows Server 2003, .Net Framework 1.1, on a box running in the client's office. The business depends on the application. Because there's a mix of classic and .Net, and the login authentication is done in Classic with a login token stored in the Classic Session object, login status is inaccessible to the .Net pages. So you can just enter the URL of a .net page and you get full access to everything. Neat! The .ASPX pages are written exactly as Classic ASP; no code-behind, absolutely no separation of UI and business logic. HTML interspersed with VB.Net. Variables are defined without any type in most cases. There is no concept of objects and absolutely no code re-use (e.g. most pages can send emails, and there's all the code needed to setup an SMTP client on every page). Some pages connect to the database using ODBC and OLEDB concurrently, and the connection strings for each are hard-coded in the pages themselves. Came across this little snippet just now... The page has about 20 bound controls, dropdown lists, all setup the same way:

                        mySelect = "select product_id, name from mytable"
                        If Request.QueryString("cust_id") <> "0" Then
                        mySelect = mySelect + " WHERE cust_id=" & Request.QueryString("cust_id")
                        End If
                        mySelect = mySelect + " order by name"
                        myDBCommand = New OleDbCommand(mySelect, myConnection)
                        myDBReader = myDBCommand.ExecuteReader()
                        lstBox1.DataSource = myDBReader
                        lstBox1.DataTextField = "name"
                        lstBox1.DataValueField = "product_id"
                        lstBox1.DataBind()
                        myDBReader.Close()
                        myDBReader = myDBCommand.ExecuteReader()
                        iLoop = 0
                        Do While myDBReader.Read And iLoop < 10000
                        If product_id = myDBReader("product_id") Then '' (product_id is set previously)
                        lstBox1.SelectedIndex = iLoop
                        iLoop = 10000
                        End If
                        iLoop = iLoop + 1
                        Loop
                        myDBReader.Close()

                        I don't know what I like least about this. The lack of validation of the querystring parameter; the concatenation of the query string into the SQL statement (ripe for SQL injection); the re-opening (i.e. re-execution) of the data reader; the looping through all the rows to match the existing value; the arbitrary limit of 10000 on the loop; the setting of the loop counter to 10000 rather than 9998 to exit the loop ... almost every line makes my head hurt. There's hundreds of pages written like this. Of which about 10% are actually used; the remainder are "old" versions of pages, but not n

                        N Offline
                        N Offline
                        Nelek
                        wrote on last edited by
                        #12

                        As long as it doesn't happen to you... Dilbert Comic Strip on 2013-02-24 | Dilbert by Scott Adams[^]

                        M.D.V. ;) If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about? Help me to understand what I'm saying, and I'll explain it better to you Rating helpful answers is nice, but saying thanks can be even nicer.

                        1 Reply Last reply
                        0
                        • D DerekT P

                          Have just been asked to take over support for a live website. It's a mix of Classic ASP and ASP.Net. It runs on Windows Server 2003, .Net Framework 1.1, on a box running in the client's office. The business depends on the application. Because there's a mix of classic and .Net, and the login authentication is done in Classic with a login token stored in the Classic Session object, login status is inaccessible to the .Net pages. So you can just enter the URL of a .net page and you get full access to everything. Neat! The .ASPX pages are written exactly as Classic ASP; no code-behind, absolutely no separation of UI and business logic. HTML interspersed with VB.Net. Variables are defined without any type in most cases. There is no concept of objects and absolutely no code re-use (e.g. most pages can send emails, and there's all the code needed to setup an SMTP client on every page). Some pages connect to the database using ODBC and OLEDB concurrently, and the connection strings for each are hard-coded in the pages themselves. Came across this little snippet just now... The page has about 20 bound controls, dropdown lists, all setup the same way:

                          mySelect = "select product_id, name from mytable"
                          If Request.QueryString("cust_id") <> "0" Then
                          mySelect = mySelect + " WHERE cust_id=" & Request.QueryString("cust_id")
                          End If
                          mySelect = mySelect + " order by name"
                          myDBCommand = New OleDbCommand(mySelect, myConnection)
                          myDBReader = myDBCommand.ExecuteReader()
                          lstBox1.DataSource = myDBReader
                          lstBox1.DataTextField = "name"
                          lstBox1.DataValueField = "product_id"
                          lstBox1.DataBind()
                          myDBReader.Close()
                          myDBReader = myDBCommand.ExecuteReader()
                          iLoop = 0
                          Do While myDBReader.Read And iLoop < 10000
                          If product_id = myDBReader("product_id") Then '' (product_id is set previously)
                          lstBox1.SelectedIndex = iLoop
                          iLoop = 10000
                          End If
                          iLoop = iLoop + 1
                          Loop
                          myDBReader.Close()

                          I don't know what I like least about this. The lack of validation of the querystring parameter; the concatenation of the query string into the SQL statement (ripe for SQL injection); the re-opening (i.e. re-execution) of the data reader; the looping through all the rows to match the existing value; the arbitrary limit of 10000 on the loop; the setting of the loop counter to 10000 rather than 9998 to exit the loop ... almost every line makes my head hurt. There's hundreds of pages written like this. Of which about 10% are actually used; the remainder are "old" versions of pages, but not n

                          T Offline
                          T Offline
                          TheGreatAndPowerfulOz
                          wrote on last edited by
                          #13

                          :rose::rose:

                          #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                          1 Reply Last reply
                          0
                          • D DerekT P

                            Have just been asked to take over support for a live website. It's a mix of Classic ASP and ASP.Net. It runs on Windows Server 2003, .Net Framework 1.1, on a box running in the client's office. The business depends on the application. Because there's a mix of classic and .Net, and the login authentication is done in Classic with a login token stored in the Classic Session object, login status is inaccessible to the .Net pages. So you can just enter the URL of a .net page and you get full access to everything. Neat! The .ASPX pages are written exactly as Classic ASP; no code-behind, absolutely no separation of UI and business logic. HTML interspersed with VB.Net. Variables are defined without any type in most cases. There is no concept of objects and absolutely no code re-use (e.g. most pages can send emails, and there's all the code needed to setup an SMTP client on every page). Some pages connect to the database using ODBC and OLEDB concurrently, and the connection strings for each are hard-coded in the pages themselves. Came across this little snippet just now... The page has about 20 bound controls, dropdown lists, all setup the same way:

                            mySelect = "select product_id, name from mytable"
                            If Request.QueryString("cust_id") <> "0" Then
                            mySelect = mySelect + " WHERE cust_id=" & Request.QueryString("cust_id")
                            End If
                            mySelect = mySelect + " order by name"
                            myDBCommand = New OleDbCommand(mySelect, myConnection)
                            myDBReader = myDBCommand.ExecuteReader()
                            lstBox1.DataSource = myDBReader
                            lstBox1.DataTextField = "name"
                            lstBox1.DataValueField = "product_id"
                            lstBox1.DataBind()
                            myDBReader.Close()
                            myDBReader = myDBCommand.ExecuteReader()
                            iLoop = 0
                            Do While myDBReader.Read And iLoop < 10000
                            If product_id = myDBReader("product_id") Then '' (product_id is set previously)
                            lstBox1.SelectedIndex = iLoop
                            iLoop = 10000
                            End If
                            iLoop = iLoop + 1
                            Loop
                            myDBReader.Close()

                            I don't know what I like least about this. The lack of validation of the querystring parameter; the concatenation of the query string into the SQL statement (ripe for SQL injection); the re-opening (i.e. re-execution) of the data reader; the looping through all the rows to match the existing value; the arbitrary limit of 10000 on the loop; the setting of the loop counter to 10000 rather than 9998 to exit the loop ... almost every line makes my head hurt. There's hundreds of pages written like this. Of which about 10% are actually used; the remainder are "old" versions of pages, but not n

                            D Offline
                            D Offline
                            David A Gray
                            wrote on last edited by
                            #14

                            I envy you not.

                            David A. Gray Delivering Solutions for the Ages, One Problem at a Time Interpreting the Fundamental Principle of Tabular Reporting

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups