0

SELECT他のセルをステートメントへの入力として使用して、Excelの単一のセル内でSQLステートメントを実行しようとしていますSELECT。いくつか検索した後、sql.request関数が私が探しているものを正確に実行することがわかりました。ただし、この関数は2002年以降廃止されたため、ここではExcel2007と2010を実行しています。引用

同じことを行うマクロ/VBAスクリプトを作成しようとしましたが、うまくいきませんでした。私はすべてのプログラミングをLabVIEW、Mathematica、SQLで行っています。VBAで何が起こっているのかわかりません。これは私が思いついたものです:

Sub Test2()

' Declare the QueryTable object. I'm not actually sure why this line is here...
Dim qt As QueryTable

' Set up the SQL Statement
sqlstring = "SELECT `Substrate ID` FROM temp_table WHERE `id`=" & Range("A1").Value

' Set up the connection string, reference an ODBC connection
connstring = "ODBC;DSN=OWT_x64;"

' Now implement the connection, run the query, and add
' the results to the spreadsheet
With ActiveSheet.QueryTables.Add(Connection:=connstring, Destination:=Range("A22"), Sql:=sqlstring)
    .Refresh BackgroundQuery:=False
End With

End Sub

上記のコードには3つの主要な問題があります。

  1. このコードは、セルA22に列ID( "Substrate ID")を返し、セルA23にSQLクエリの結果を返します。結果だけが必要で、セルA22にのみ必要です。すべてのクエリは、1行と1列のみを返すように強制されます。
  2. スクリプトの実行時に出力セルA22がアクティブなセルになるようにする方法がわかりません。また、入力セルA1は、アクティブセルのすぐ左側(列1)のセルである必要があります。
  3. これをExcel関数に変換する方法がわかりません

    =sql.request(connection_string,[output_ref],[driver_prompt],[query_text],[col_names_logical])

    これが私の最終目標です。このようにして、このコードを会社の他の人に渡して、彼らが簡単に使用できるようにすることができます。

接続は、MySQL5.6データベースへのODBC接続です。クエリは非常に単純で、次のようになります。

SELECT column FROM table WHERE id=excel_cell_value

あなたが私が持っているVBAコードからわかるように。

現在、「id」列と「Substrate ID」列のすべての行を返す別のExcelワークシートでクエリを実行してから、実行VLOOKUPして目的のアイテムを検索しています。データベースのサイズが急速に拡大しているため、これが問題になり始めています。

だから、私は尋ねます:

  1. 結果の列IDを削除するにはどうすればよいですか?
  2. これをカスタムExcel関数に変換するにはどうすればよいですか?Office.comを見ましたが、それほど難しくはないようですが、最初に動作するスクリプトが必要です。
  3. -または-誰かが共有したいカスタム関数をすでに作成しましたか?

ありがとう!

編集:ティムのリンクのおかげでなんとかうまくいくことができました。

Function SQLQuery(sqlString As String, connString As String, Optional TimeOut As Integer) As String

SQLQuery = Error 'Assume an error happened

Dim conn As ADODB.Connection
Dim record As ADODB.Recordset

Set conn = New ADODB.Connection
conn.ConnectionString = connString
conn.Open
Set record = New ADODB.Recordset

If TimeOut > 0 Then
    conn.CommandTimeout = TimeOut
End If

record.Open sqlString, conn

Dim cols As Long
Dim i As Long

cols = record.Fields.Count   'Count how many columns were returned
If Not record.EOF Then   'Put results into comma-delimited string
    record.MoveFirst
    s = ""
    If Not record.EOF Then
        For i = 0 To cols - 1
            s = s & IIf(i > 0, ",", "") & record(i)
        Next i
    End If
End If

SQLQuery = s

End Function

ただし、かなり遅いです。それをスピードアップする方法について何かアイデアはありますか?

4

1 に答える 1

1

これは、接続をキャッシュする簡単なテストです。100回のルックアップを含むテストワークシートでは、計算時間が約18秒から約0.5秒に短縮されました。

ただし、Excelを閉じる(またはVB環境がリセットされる)まで接続は開いたままになります。

環境の違いをテストする場合は、マークされた行をコメントアウトできます(静的変数をクリアするには、VBEの[停止]ボタンも押すことを忘れないでください)。

Function SQLQuery(sqlString As String, connString As String, _
                                  Optional TimeOut As Integer) As String

    Static cs As String
    Static conn As ADODB.Connection

    SQLQuery = Error 'Assume an error happened
    Dim s

    If conn Is Nothing Or connString <> cs Then
        Set conn = New ADODB.Connection
        conn.ConnectionString = connString
        conn.Open
        If TimeOut > 0 Then conn.CommandTimeout = TimeOut
        cs = connString '###comment this out to disable caching effect
    End If

    Dim record As New ADODB.Recordset

    record.Open sqlString, conn

    Dim cols As Long
    Dim i As Long

    cols = record.Fields.Count   'Count how many columns were returned
    If Not record.EOF Then   'Put results into comma-delimited string
        record.MoveFirst
        s = ""
        If Not record.EOF Then
            For i = 0 To cols - 1
                s = s & IIf(i > 0, ",", "") & record(i)
            Next i
        End If
    End If

    SQLQuery = s

End Function
于 2012-05-04T20:27:15.440 に答える