0

On the userform there are a few textboxes. When an item in the combobox is chosen, only some of them stay visible. I want to step through visible textboxes at that time and fill them with data from SQL Server database. Items on the combobox list are identical with table names so it becomes a parameter in the SQL statement.

Debugging the code an error pops up while executing the statement (it runs fine in Management Studio). Maybe I'm missing some characters like ' or " or a whitespace (but the code isn't in red) or there is something wrong with the code and using recordset itself:

    Private Sub cboTyp_AfterUpdate()

Dim rs As ADODB.Recordset
Dim Nazwa As String
Dim Skr As String
Dim Kolumna As String
Dim c As Control

On Error Resume Next
For Each c In Me.Controls
    Select Case c.TabIndex
        Case 3 To 10:
            If c.Visible = True Then
            Nazwa = c.Name
            Skr = Right(Nazwa, 5)

            On Error GoTo Nazwa_Initialize_Err:
            Set rs = New ADODB.Recordset

                rs.Open "SELECT DISTINCT c.name AS NazwaKolumny FROM sys.columns c JOIN sys.tables t ON c.object_id = t.object_id" & _
                            " WHERE c.name LIKE '%" & Skr & "';", _
                                con, adOpenStatic
                Kolumna = rs.Fields("NazwaKolumny")
                rs.Close
                Set rs = Nothing

                'Wyszukanie ostatniej wartości dla wybranej składowej
                    Set rs = New ADODB.Recordset
                    rs.Open "Declare @sqlCommand varchar(max)" & _
                                " Declare @columnName varchar(250)" & _
                                " Set @columnName = (SELECT DISTINCT c.name FROM sys.columns c JOIN sys.tables t ON c.object_id = t.object_id" & _
                                " WHERE c.name LIKE '%" & Skr & "')" & _
                                " Set @sqlCommand = 'SELECT [' + @columnName + ']' + " & _
                                " 'FROM [" & cboTyp.Value & "] WHERE ID = (SELECT MAX(ID) FROM [" & cboTyp.Value & "])'" & _
                                " Exec (@sqlCommand);", _
                                    con, adOpenStatic

                'Jeżeli brak wartości (zwróci NULL) oznacza to przejdź do normalnego wstawiania
                    If rs.RecordCount = 0 Then
                        c.SetFocus
                    'Jeśli znajdzie wartość to ją wstaw
                    Else
                        rs.MoveFirst
                            Do
                                Nazwa = rs.Fields(Kolumna)
                                rs.MoveNext
                            Loop Until rs.EOF
                    End If
            End If
    End Select
Next
On Error GoTo 0

'Opuszczanie pola - zamknięcie i wyczyszczenie Recordset
Nazwa_Initialize_Exit:
    On Error Resume Next
    rs.Close
    Set rs = Nothing

Exit Sub
4
  • On what line does the error occur? (remove the handler) Commented Jul 20, 2015 at 11:18
  • debug.print the SQL then copy/paste into SSMS and check its validity (your sub-q will return > 1 row atm so it will fail Commented Jul 20, 2015 at 11:20
  • This is bad idea to use diacritic characters in the names of variables, like: Dim Skrócona As String Commented Jul 20, 2015 at 11:32
  • Changed by the way as well. Commented Jul 21, 2015 at 8:25

2 Answers 2

2

EDIT please assign a new recordset object to it before using, for eg

Removed the SET NOCOUNT ON. It is mostly required for stored procs.

    set rs= New ADODB.Recordset

   rs.CursorLocation = ADODB.CursorLocationEnum.adUseClient
   rs.Open "Declare @sqlCommand varchar(max)" & _
                        " Declare @columnName varchar(250)" & _
                        " Set @columnName = (SELECT DISTINCT c.name FROM sys.columns c JOIN sys.tables t ON c.object_id = t.object_id" & _
                        " WHERE c.name LIKE '%" & Skrócona & "')" & _
                        " Set @sqlCommand = 'SELECT ' + '[' + @columnName + ']' + " & _
                        "' FROM [" & cboTyp.Value & "] WHERE ID = (SELECT MAX(ID) FROM [" & cboTyp.Value & "])'" & _
                        " Exec (@sqlCommand);", _
                            con, adOpenStatic

NEW

Also added the rs.CursorLocation for proper recordcount.

Sign up to request clarification or add additional context in comments.

5 Comments

SET NOCOUNT ON is a bit random but the missing New is the problem.
Removed the NOCOUNT ON. It was not necessary. Thanks.
Yes, setting new recordset was the problem.
@ user3081756 I've edited the question because recordcount says -1 when there are no records in the database in current table. Any idea ?
I think in case of ADODB.Recordset you also need to set the cursor location to get the proper recordcount. You can find some detail in here. Also I have added the code for it above
0

You have extra single quotes at the beggining and end of:

"' FROM [" & cboTyp.Value & "] WHERE ID = (SELECT MAX(ID) FROM [" & cboTyp.Value & "])'"

I wouldn't suggest such a code that is prone to SQL injection attacks and use parameters instead. Check sp_ExecuteSQL in help for samples.

3 Comments

Would this really be prone to SQL injection ? Parameter is a table name from tables list. The source list can be placed in a protected worksheet to avoid any changes or extracted from database with a sql statement.
Yes it would. The most obvious one is in the where clause. Probably you are not allowing your users to select the possible values from a list. No idea what the source of "Skrócona" is. If you are allowing its value to be set from an input then you are wide open to attack.
It's a few characters from control's name used to find the column name so no input here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.