user2140261のソリューションと同様に、worksheet_changeイベントを使用して変更をトリガーします。
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" Then
With ActiveSheet.Range("Table_Name").ListObject.QueryTable
.CommandText = ChangeParameter(.CommandText, "ParameterFlag", Range(Target.Address))
End With
ActiveWorkbook.RefreshAll
End If
End Sub
上記では、$ A $ 1は動的情報(日付など)の場所であり、SQLテーブルはTable_Nameであり、ParameterFlagは置換するSQLコード内のパラメーターです(以下を参照)。これは、SQLコードを変更するために使用されるChangeParameter関数です。
Function ChangeParameter(src As String, parameter As String, newValue As String)
'Replace src text surrounded by startParameter and endParameter with newValue
Dim startPosn As Long, endPosn As Long
Dim startParameter As String, endParameter As String
startParameter = "/*<" & parameter & ">*/"
endParameter = "/*</" & parameter & ">*/"
startPosn = 0
Do
startPosn = InStr(startPosn + 1, src, startParameter)
If startPosn Then
endPosn = InStr(startPosn + Len(startParameter), src, endParameter)
If endPosn Then
src = Left(src, startPosn + Len(startParameter) - 1) & newValue & Mid(src, endPosn)
Else
Exit Do
End If
End If
Loop While startPosn
ChangeParameter = src
End Function
目的のSQLコードが次の場合、たとえば次のようになります。
SELECT * FROM mytable WHERE startDate > '7/1/2015'
次に、これをコマンドテキストボックスで編集して次のようにします。
SELECT * FROM mytable WHERE /*<StartDate>*/'7/1/2015'/*</StartDate>*/
そして、呼び出し線は次のようになります。
.CommandText = ChangeParameter(.CommandText, "StartDate", "'" & Range(Target.Address) & "'")
(日付は定数としてコードに格納されるため、スプレッドシートの値を一重引用符で囲む必要があります)。/* */
行の途中にある場合でも、囲まれたコメントは無視されるため、これはすべて機能します。通常、コーディング方法は不十分ですが、ここでは役立ちます。
/*<StartDate>*/
パラメータフラグ(この場合は)で囲まれた元のSQLコード内のすべての場所は/*</StartDate>*/
、新しい値(この場合は "'"&Range(Target.Address)& "'")に置き換えられます。次にターゲットセル$A$ 1が変更されると、呼び出しが再度実行され、以前の値が何であったかを知る必要なしにパラメーターが再度変更されます。
ChangeParameterの複数の呼び出しは、変更するパラメーターごと、および変更するパラメーターを含むSQLベースのテーブルごとに使用できます。
もちろん、パラメータの置換が複雑なコードで機能する場合は、これは必要ありません...