Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

convert sql to vba string

Status
Not open for further replies.

vba317

Programmer
Mar 5, 2009
708
US
I have found a faq on this website FAQ705-6112 to convert an SQL string to workable vba.
I am getting an error 3265 Item not found in this collection.
I have set up a form called frmSQL1
On the form I have an input textbox called txtSQL
a command button called cmdSQL
code behind the command box
I have another text box on the form called txtVba
I am hoping that I can get the code once completed to output to this box
I have highlighted in blue where the error is happening. Is it possible I am missing a reference?

Any help is appreciated

Tom


Code:
Private Sub cmdSQL_Click()
Dim qDefName As String
Call convertSQLToStdStr(txtSQL)
End Sub

Code:
Public gpaSStoks()     'An array of substitution tokens
Public gpaSSputs()     'A matching array of replacements
Public Function stdStr(varNumOrString) As String
'see ssArrays 'trying to make string construction less than totally awkward
'pass a string to append to static string (direct abutment -- no space)
'pass any number (e.g. False) to reset the string
'Always returns existing string whatever the state
'anything in global array gpaSStoks will be replaced by the respective gpaSSputs content 'character "~" is always replaced by vbcrlf
'see ssArrays to set substitution arrays
'remember not to transfer control while string is under construction
    Static theString As String
    If VarType(varNumOrString) <> vbString Then
        stdStr = theString
        theString = ""
    Else
        On Error Resume Next
        x = Replace(varNumOrString, "~", vbCrLf)
        'return substitute
        'these from convertSQLToStdStr
        x = Replace(x, Chr(168), Chr(34))
        'quote substitute
        x = Replace(x, "`", "'")
        'apostrophe substitute
        On Error Resume Next
        For i = 0 To UBound(gpaSStoks)
            If Err <> 0 Then Exit For
            If Len(gpaSStoks(i)) > 0 Then
                x = Replace(x, gpaSStoks(i), gpaSSputs(i))
            End If
        Next i
        theString = theString & x
        stdStr = theString
    End If
End Function
Public Function ssArrays(findIt, Putit) As Integer
'set values into public arrays for stdStr substitution
'see stdStr or this won't make sense 'reset the arrays by passing both findit and putit as zero length ( "" )
    Dim i As Integer
    Dim done As Boolean
    Static once
    'On Error Resume Next
    'if ubound(gpaSStoks) then goto
    If Not once Then    '
        ReDim gpaSStoks(0)
        ReDim gpaSSputs(0)
    Else    'look to replace current findit with putit
        For i = 0 To UBound(gpaSStoks)
            If gpaSStoks(i) = findIt Then
                gpaSSputs(i) = Putit
                done = True
                Exit For
            End If
        Next i
    End If
    If Not done Then
        'didn't happen, insert both
        If once Then
            ReDim Preserve gpaSStoks(i)
            ReDim Preserve gpaSSputs(i)
        End If
        gpaSStoks(i) = CStr(findIt)
        gpaSSputs(i) = CStr(Putit)
    End If
    If (Len(findIt) = 0) And (Len(Putit) = 0) Then
        'erase 'command' none of the above mattered...
        ReDim gpaSStoks(0)
        ReDim gpaSSputs(0)
        once = False    'reset to reuse a(0) next time
    Else
        once = True
    End If
    ssArrays = UBound(gpaSStoks)
End Function

Public Function convertSQLToStdStr(qDefName As String)
'Convert the SQL from qdefName (default TEMP)
'to stdSTR function calls.
'Allows SQL to be fully tested and then literally
'cut and pasted into code from the immediate window
'See also functions stdStr and SSarrays
    Dim qD As QueryDef
    Dim dBs As Database
    Dim pH As String, qDn As String, qdSQL As String, sniP As String
    Dim pT As Integer, epT As Integer
    If IsMissing(qDefName) Then
        qDn = "temp"
    Else
        qDn = qDefName
    End If
    Set dBs = CurrentDb()
[Blue]    Set qD = dBs.QueryDefs(qDn) [/Blue]
    qdSQL = Replace(qD.SQL, vbCrLf, "~")
    Debug.Print "stdStr false   'reset"
    Do While epT < Len(qdSQL)
        pT = epT + 1
        epT = InStr(pT, qdSQL, "~")
        If epT = 0 Then
            epT = Len(qdSQL)
        End If
        sniP = pH & Mid(qdSQL, pT, epT - pT)
        'next 2 will be restored by stdSTR
        sniP = Replace(sniP, Chr(34), Chr(168))
        'Hide the Quote character from VBA
        sniP = Replace(sniP, "'", "`")
        'Hide the apostrophe from vba
        pH = "~"
        Debug.Print "stdStr " & Chr(34) & sniP & Chr(34)
    Loop
    Debug.Print "SQL = stdStr(False)   'fetch and reset"
End Function
 
What is the value of qDn at the time the error raises ?

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
The string that I have pasted into txtSQL which is:

INSERT INTO tbl_MisDirectedCash ( UCI, BillMonth, [Trans Type], PatName, AcctNu, AID, EID, SLID, TranID, TranCode, Amount )
SELECT imp_CS.Client AS UCI, imp_CS.[Bill Mon of Trans] AS BillMonth, imp_CS.[Trans Type], [_MisDirectedAcct].PatName, [_MisDirectedAcct].AcctNu, PatIntIDFromEncID([EncId]) AS AID, EncNumFromEncID([EncId]) AS EID, SLIDNumFromTranID([Serv Line Id]) AS SLID, TranNumFromTranID([Serv Line Id]) AS TranID, IIf([Trans Type]=2,[Debit Code Sd],[Payment Code Sd]) AS TranCode, imp_CS.Amount
FROM imp_CS INNER JOIN _MisDirectedAcct ON imp_CS.[Account Number] = [_MisDirectedAcct].AcctNu
WHERE (((imp_CS.[Trans Type])=2 Or (imp_CS.[Trans Type])=4))
ORDER BY imp_CS.[Trans Type], PatIntIDFromEncID([EncId]), EncNumFromEncID([EncId]), SLIDNumFromTranID([Serv Line Id]), TranNumFromTranID([Serv Line Id]);
 
I put a debug.print qDn before the Set qD = dBs.QueryDefs(qDn)line and I got the following code in the immediate window

"SELECT imp_CS.Client AS UCI, imp_CS.[Bill Mon of Trans] AS BillMonth, imp_CS.[Trans Type], [_MisDirectedAcct].PatName, [_MisDirectedAcct].AcctNu, PatIntIDFromEncID([EncId]) AS AID, EncNumFromEncID([EncId]) AS EID, SLIDNumFromTranID([Serv Line Id]) AS SLID, TranNumFromTranID([Serv Line Id]) AS TranID, IIf([Trans Type]=2,[Debit Code Sd],[Payment Code Sd]) AS TranCode, imp_CS.Amount " & vbCrLf & _
"FROM imp_CS INNER JOIN _MisDirectedAcct ON imp_CS.[Account Number] = [_MisDirectedAcct].AcctNu " & vbCrLf & _
"WHERE (((imp_CS.[Trans Type])=2 Or (imp_CS.[Trans Type])=4)) " & vbCrLf & _
"ORDER BY imp_CS.[Trans Type], PatIntIDFromEncID([EncId]), EncNumFromEncID([EncId]), SLIDNumFromTranID([Serv Line Id]), TranNumFromTranID([Serv Line Id]);"


Tom
 
Sorry,
I didnt copy the full string I just realized it.

strSql = "INSERT INTO tbl_MisDirectedCash ( UCI, BillMonth, [Trans Type], PatName, AcctNu, AID, EID, SLID, TranID, TranCode, Amount ) " & vbCrLf & _
"SELECT imp_CS.Client AS UCI, imp_CS.[Bill Mon of Trans] AS BillMonth, imp_CS.[Trans Type], [_MisDirectedAcct].PatName, [_MisDirectedAcct].AcctNu, PatIntIDFromEncID([EncId]) AS AID, EncNumFromEncID([EncId]) AS EID, SLIDNumFromTranID([Serv Line Id]) AS SLID, TranNumFromTranID([Serv Line Id]) AS TranID, IIf([Trans Type]=2,[Debit Code Sd],[Payment Code Sd]) AS TranCode, imp_CS.Amount " & vbCrLf & _
"FROM imp_CS INNER JOIN _MisDirectedAcct ON imp_CS.[Account Number] = [_MisDirectedAcct].AcctNu " & vbCrLf & _
"WHERE (((imp_CS.[Trans Type])=2 Or (imp_CS.[Trans Type])=4)) " & vbCrLf & _
"ORDER BY imp_CS.[Trans Type], PatIntIDFromEncID([EncId]), EncNumFromEncID([EncId]), SLIDNumFromTranID([Serv Line Id]), TranNumFromTranID([Serv Line Id]);"


 
So, it's definitively NOT the name of a query ...

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Am I supposed to be entering the name of the query instead of the contents of the query?

Tom
 
theFAQ said:
convertSQLToStdStr converts the SQL in a saved query to stdStr code lines

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Ok that was easy. I see from stepping through the code that a new line gets created with each loop from the Debug.Print "stdStr " & Chr(34) & sniP & Chr(34)
statement. How could I go about adding each string together so the final string gets put back onto the output of my form in the txtVba textbox?

Tom
 
I hav attempted to use arrays to combine the strings as they get added together. I am getting a compile error and I can't figure out why. I would be thankful for any help provided.

Tom

Code:
Public Function convertSQLToStdStr(qDefName As String)
'Convert the SQL from qdefName (default TEMP)
'to stdSTR function calls.
'Allows SQL to be fully tested and then literally
'cut and pasted into code from the immediate window
'See also functions stdStr and SSarrays
    Dim qD As QueryDef
    Dim dBs As Database
    Dim pH As String
    Dim qDn As String
    Dim qdSQL As String
    Dim sniP As String
    Dim pT As Integer, epT As Integer
    Dim intCnt As Integer
    Dim strSQL As String
    Dim strSQLA(10) As Variant
    If IsMissing(qDefName) Then
        qDn = "temp"
    Else
        qDn = qDefName
    End If
    Set dBs = CurrentDb()
    'Debug.Print qDn
    Set qD = dBs.QueryDefs(qDn)
    qdSQL = Replace(qD.SQL, vbCrLf, "~")
    Do While epT < Len(qdSQL)
        intCnt = 1 + intCnt
        pT = epT + 1
        epT = InStr(pT, qdSQL, "~")
        If epT = 0 Then
            epT = Len(qdSQL)
        End If
        sniP = pH & Mid(qdSQL, pT, epT - pT)
        'next 2 will be restored by stdSTR
        sniP = Replace(sniP, Chr(34), Chr(168))
        'Hide the Quote character from VBA
        sniP = Replace(sniP, "'", "`")
        'Hide the apostrophe from vba
        'pH = "~"
        'Debug.Print "ph", pH
        If intCnt = 1 Then strSQLA(intCnt) = "strSQL = " & Chr(34) & sniP & Chr(34) & "  & _"
        If intCnt > 1 Then strSQLA(intCnt) = Chr(34) & sniP & Chr(34) & "  & _"
        If intCnt = 2 Then strSQLA (1) + strSQLA(2)
        If intCnt = 3 Then strSQLA (1) + strSQLA(2) + strSQLA(3)
        If intCnt = 4 Then strSQLA (1) + strSQLA(2) + strSQLA(3) + strSQLA(4)
        If intCnt = 5 Then strSQLA (1) + strSQLA(2) + strSQLA(3) + strSQLA(4) + strSQLA(5)
        Debug.Print "strSQL ", strSQL
        Debug.Print "strSQLA(1)", strSQLA(1)
        Debug.Print "strSQLA(2)", strSQLA(2)
        Debug.Print "strSQLA(3)", strSQLA(3)
        Debug.Print "strSQLA(4)", strSQLA(4)
        Debug.Print "strSQLA(5)", strSQLA(5)
    Loop
 
The compile error happens on this line
If intCnt = 2 Then strSQLA (1) + strSQLA(2)
 
I want to store the each line of the SQL code as they are compiled into a seperate array and combine those arrays. I have fixed the compile error but now I have two issues that I am having a problem with. How to define the last line because on the last line I need to eliminate the carrage return and the & _ character. My second problem is how to shorten the length of the sql code. An example is:
my second line is:
"SELECT dbo_dic_Period.pd AS rptpd, tbldic_POS.ID AS provID, tbldic_POS.ID AS posID, Sum(tmp_MthStatsBaaProvPos.[SumOfCountOfCase #]) AS CaseCnt, Sum(tmp_MthStatsBaaProvPos.SumOfSumOfUnits) AS Units, Sum(tmp_MthStatsBaaProvPos.[SumOfCountOfOR Flag]) AS ORFlag, Sum(tmp_MthStatsBaaProvPos.[SumOfSumOfOR Units]) AS ORUnits, Sum(tmp_MthStatsBaaProvPos.SumOfSumOfAmt) AS Amt, Sum(tmp_MthStatsBaaProvPos.SumOfSumOfTotpay) AS TotPay, Sum(tmp_MthStatsBaaProvPos.SumOfSumOfTotadj) AS TotAdj, Sum(tmp_MthStatsBaaProvPos.SumOfSumOfCurBal) AS CurBal, Sum(tmp_MthStatsBaaProvPos.Last3MonChgs) AS 3MonChgs" & _

For readability sake I would like to Have the line appear like this:
"SELECT dbo_dic_Period.pd AS rptpd, tbldic_POS.ID AS provID, tbldic_POS.ID AS posID, Sum(tmp_MthStatsBaaProvPos.[SumOfCountOfCase #]) AS CaseCnt, " & _

So the question is how could I combine the len statement with the find, statement to find the end of this line and add an " & _ at the end?


Tom


Code:
 If intCnt = 1 Then strSQLA(intCnt) = "strSQL = " & Chr(34) & sniP & Chr(34) & "  & _" & Chr(10)
        If intCnt = 1 Then strSQL = strSQLA(1)
        If intCnt > 1 Then strSQLA(intCnt) = Chr(34) & sniP & Chr(34) & "  & _" & Chr(10)
        'If intCnt = 2 Then strSQL = strSQLA(2) = Chr(34) & sniP & Chr(34) & "  & _"
        If intCnt = 2 Then strSQL = strSQLA(1) + strSQLA(2)
        If intCnt = 3 Then strSQL = strSQLA(3) = Chr(34) & sniP & Chr(34) & "  & _"
        If intCnt = 3 Then strSQL = strSQLA(1) + strSQLA(2) + strSQLA(3)
        If intCnt = 4 Then strSQL = strSQLA(4) = Chr(34) & sniP & Chr(34) & "  & _"
        If intCnt = 4 Then strSQL = strSQLA(1) + strSQLA(2) + strSQLA(3) + strSQLA(4)
        If intCnt = 5 Then strSQL = strSQLA(5) = Chr(34) & sniP & Chr(34) & "  & _"
        If intCnt = 5 Then strSQL = strSQLA(1) + strSQLA(2) + strSQLA(3) + strSQLA(4) + strSQLA(5)
        If intCnt = 6 Then strSQL = strSQLA(6) = Chr(34) & sniP & Chr(34) & "  & _"
        If intCnt = 6 Then strSQL = strSQLA(1) + strSQLA(2) + strSQLA(3) + strSQLA(4) + strSQLA(5) + strSQLA(6)
        If intCnt = 7 Then strSQL = strSQLA(7) = Chr(34) & sniP & Chr(34) & "  & _"
        If intCnt = 7 Then strSQL = strSQLA(1) + strSQLA(2) + strSQLA(3) + strSQLA(4) + strSQLA(5) + strSQLA(6) + strSQLA(7)
        If intCnt = 8 Then strSQL = strSQLA(8) = Chr(34) & sniP & Chr(34) & "  & _"
        If intCnt = 8 Then strSQL = strSQLA(1) + strSQLA(2) + strSQLA(3) + strSQLA(4) + strSQLA(5) + strSQLA(6) + strSQLA(7) + strSQLA(8)
        If intCnt = 9 Then strSQL = strSQLA(9) = Chr(34) & sniP & Chr(34) & "  & _"
        If intCnt = 9 Then strSQL = strSQLA(1) + strSQLA(2) + strSQLA(3) + strSQLA(4) + strSQLA(5) + strSQLA(6) + strSQLA(7) + strSQLA(8) + strSQLA(9)
        If intCnt = 10 Then strSQL = strSQLA(10) = Chr(34) & sniP & Chr(34) & "  & _"
        If intCnt = 10 Then strSQL = strSQLA(1) + strSQLA(2) + strSQLA(3) + strSQLA(4) + strSQLA(5) + strSQLA(6) + strSQLA(7) + strSQLA(8) + strSQLA(9) + strSQLA(10)
       
        
        Debug.Print strSQL
 
I have a little application (written in VB.NET) that does what you are after, I think.
I create my SQLs in another app (SQL builder), so I start with something like this:

[pre]
SELECT A.FIELD1, A.FIELD2,
B.FIELDA, B.FIELDB
FROM SOME_TABLE A, OTHER_TABLE B
WHERE A.PK_FIELD = B.FK_FIELD
AND A.FIELD_X = '1234'
ORDER BY B.FIELDC[/pre]

I take this SQL and dump it into a text box in my little app.

In my one command button I do:

First, I go line-by-line and remove any multiple spaces leaving just one space.
Then I add [blue]"[/blue] at the beginning of very first line.
I add [blue]& "[/blue] at the beginning of every line after that.
At the end of each line, I add [blue]" & vbNewLine[/blue] (except of the last line).
At the end of the last line I simply add [blue]"[/blue]
Then I take whatever is in the text box and dump it into a Clipboard

At this time in my text box I have:
[pre][blue]
"SELECT A.FIELD1, A.FIELD2, " & vbNewLine _
& " B.FIELDA, B.FIELDB " & vbNewLine _
& " FROM SOME_TABLE A, OTHER_TABLE B " & vbNewLine _
& " WHERE A.PK_FIELD = B.FK_FIELD " & vbNewLine _
& " AND A.FIELD_X = '1234' " & vbNewLine _
& " ORDER BY B.FIELDC"
[/blue][/pre]
which allows me to go to my code and type:[tt]
strSQL = [Ctrl-V][/tt]
which pastes whatever I have in a Windows Clipboard into my code.

At the end, I have in my code:

[pre]
strSQL = "SELECT A.FIELD1, A.FIELD2, " & vbNewLine _
& " B.FIELDA, B.FIELDB " & vbNewLine _
& " FROM SOME_TABLE A, OTHER_TABLE B " & vbNewLine _
& " WHERE A.PK_FIELD = B.FK_FIELD " & vbNewLine _
& " AND A.FIELD_X = '1234' " & vbNewLine _
& " ORDER BY B.FIELDC"
[/pre]

Works like a dream for several years now, and my co-workers use it as well and they love it.


Have fun.

---- Andy
 
Andy, I see 2 problems if your SQL code contains something like this:
Code:
AND A.FIELD_X = "1234     012"

Tom, I still don't understand the convoluted way you follow.
I'd use the Split function, a loop and then a Join function.

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Andy,
Would this work for access 2003 vba?

Tom
 
My logic is convoluted mostly from my lack of understanding. I will try and use the split funtion and see where it gets me.

Tom
 
PHV - I see your point, but I use hard coded values in my SQL only at the beginning, I replace them with Variables, so my final SQL would look like:

[pre]
strSQL = "SELECT A.FIELD1, A.FIELD2, " & vbNewLine _
& " B.FIELDA, B.FIELDB " & vbNewLine _
& " FROM SOME_TABLE A, OTHER_TABLE B " & vbNewLine _
& " WHERE A.PK_FIELD = B.FK_FIELD " & vbNewLine _
& " AND A.FIELD_X = '[blue]" & txtSomeTextBox.Text & "[/blue]' " & vbNewLine _
& " ORDER BY B.FIELDC"
[/pre]

vba317, I use the same app in VBA. It is - like I said - just to convert one string to another, but since I have noticed long time ago that I had to do it over and over, and over again 'by hand', why not create something that will do it for me. :)

I can give you the EXE of that app, no problem, but I don't know how to do it outside TT since the exchange of e-mail addresses is a 'no-no' here (which I totty understand and support)


Have fun.

---- Andy
 
To accomplish what I’ve mentioned above in VBA:

Place a text box on your UserForm, name it txtText
Set its MultiLine property to True
(and EnterKeyBehavior property to True if needed)

In the command button's Click even paste this code:

Code:
Dim i As Integer

If Strings.InStr(txtText.Text, "&") Or Strings.InStr(txtText.Text, Chr(34)) Then
    Call MsgBox("You already have & and/or " & Chr(34) & " in your SQL", _
        vbInformation, "Invalid Characters.")
    Exit Sub
End If

Dim arySQL() As String
Dim strNewSQL As String
[green]
'Get rid of all multiple Spaces, keep just 1 space[/green]
Do While Strings.InStr(txtText.Text, "  ")
    txtText.Text = Strings.Replace(txtText.Text, "  ", " ")
Loop

arySQL = Strings.Split(txtText.Text, vbNewLine)

For i = LBound(arySQL) To UBound(arySQL)
    Select Case i
        Case LBound(arySQL)     [green]'First line[/green]
            strNewSQL = strNewSQL & Chr(34) & Strings.Trim(arySQL(i)) & " " & Chr(34) & " & vbNewLine _" & vbNewLine
        Case UBound(arySQL)     [green]'Last line[/green]
            If Strings.Len(arySQL(i)) > 0 Then
                strNewSQL = strNewSQL & "& " & Chr(34) & " " & Strings.Trim(arySQL(i)) & Chr(34)
            End If
        Case Else               [green]'All lines in between[/green]
            If Strings.Len(arySQL(i)) > 0 Then
                strNewSQL = strNewSQL & "& " & Chr(34) & " " & Strings.Trim(arySQL(i)) & " " & Chr(34) & " & vbNewLine _" & vbNewLine
            End If
    End Select
Next

With txtText
    .Text = strNewSQL
    .ForeColor = vbBlue
    
    [green]'Place text in Clipboard[/green]
    Dim MyData As New DataObject
    
    MyData.SetText .Text
    MyData.PutInClipboard
End With

I did that in Excel, but it should work in Access as well...

Have fun.

---- Andy
 
Andy,
Thank you . I thought that you had to have quotes at the beginning and end of every line with the & _ at the end of the line?

Tom
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top