申し訳ありません。これは長いです。あなたの質問への2番目の答え、そして私の最初の答えの延長。私の目は最後に疲れていた。奇妙なタイプミスや一見不足している文章は許してください。あなたの目が途中で釉薬をかけると、最後には実際の作業コード(私が望む)があります。
牛、これは雄牛です。しかし、私は鞍を投げ、私は最初にOPに答えた昨日の朝からそれを乗っていました。私は問題はDB2の奇妙さではないと思うが(私がまだ理解できない限り、笑)、ExcelがODBC、SQL、およびクエリを実装する方法のせいである。
私はこれを学習の練習にすることにしました。私はAccess VBAで一日中仕事をしていましたが、時折Excelに入ろうとしましたが、以前はExcelのクエリに夢中になったことはありませんでした。私は、ノーヘルプファイル、VBAオブジェクトエクスプローラ、およびMSDNのオンラインドキュメントを見てきました。しかし、それはまだ記念碑的に混乱していました。 https://www.cimaware.com/expert-zone/creating-basic-data-reports-with-listobjects-and-querytables
複数のExcel UIブランキングがあり、関連付けられたコレクションのVBAオブジェクト階層が&のオブジェクトであることができるこのWebページが見つかりました。複数の、時には同時に短縮形&パラレルフォームを取る。これは、Excelがすべての場所で物事を投げる方法を少しクレイジーだ:>QueryTable/s
1)Excel
>Workbook/s
>Connections
>WorkbookConnection
>ODBCConnection
2)Excel
>Workbook/s
>Worksheet/s
>ListObject/s
3)Excel
>Workbook/s
>Worksheet/s
>QueryTable/s
4 )ListObject
>QueryTable
>WorkbookConnection
5)QueryTable
>WorkbookConnection
私はすべてのこれらの項目を説明します
:
Excel
、Workbooks
は、Workbook
、Worksheets
、およびWorksheet
は明白です。
- 各
Workbook
には、Worksheet
ごとにConnections
のコレクションが含まれています。
Connections
は、それがTXT
またはXLS
からファイルベースであるかどうか、任意のタイプの接続を持っているウェブベースのHTTP
経由、または我々は密接にここを見ている1することができます:ODBC
。
- 何らかの理由でMicrosoftが命名規則を破って、
Connection
ではなくWorkbookConnection
と呼ばれていました。
- 次に、
ODBCConnection
に到着します。ODBCConnection
には、ODBC設定が大量に組み込まれています。
- これらの項目全体で、ODBC接続文字列とSQLクエリ文字列がすべて繰り返されて混乱することがあります。また、ある項目/オブジェクトが1つの項目を別の項目にリンクさせるのは難しい場合もあります。
ListObject
(LO)に含まれているか、またはワークシート上で独立してライブできる2つの場所でQueryTable
(QT)を作成できます。
- QTがLOに含まれている場合(Excel 2007で導入されたように)、これは私が言及したブリングのいくつかを示しています。具体的には、
Table Tools
グループとDesign
タブがリボンにあります。これは、列ヘッダー上の交互の行の色やドロップダウンボックスなど、すべてのファンシー設定&の形式です。
- QTがLOと独立している場合、結果のクエリ結果&はシンプルで実用的です。実際、彼らはExcel 2003と同じように見えるし、機能します。>
ODBCConnection
1)Excel
>Workbook/s
>Connections
>WorkbookConnection
接続が格納されている場所です。これは、[データ]> [接続]のリボンから[ワークブック接続]ウィンドウに表示される接続と同じです。 >QueryTable/s
2)Excel
>Workbook/s
>Worksheet/s
>ListObject/s
これはExcelのUIで最初からクエリを作成するときに、「外部データの取り込み」グループ内の項目のいずれかを使用することにより、得るものですその結果、SQLサーバーへのODBC接続が発生します。私の場合、すでにDB2用のDSNファイルのコレクションがあります。この実験では、すべて「既存の接続」ウィンドウにリストされているDSNファイルしか使用していませんでした。 >QueryTable/s
3)Excel
>Workbook/s
>Worksheet/s
これは、あなたがプログラムでスタンドアロンQueryTable
ListObject
に含まれていない作成するVBAを使用している場合、あなたが得るものです。これまで私はUIでこれを行う方法を見つけていませんでした。私は何が行われても、Excel 2007以降のUIを使用して作成されたクエリは、ListObject
内に強制的に格納されていると考えています。 >WorkbookConnection
4)ListObject
>QueryTable
オブジェクトのこのチェーンは、あなたがUIから得るものです。あらかじめConnections
コレクションにWorkbookConnection
を明示的に作成する必要はないことがわかりました。 QueryTable
が作成されるたびに、接続は常に一種の副産物として作成されます。
5)QueryTable
>WorkbookConnection
これは結局、今
おそらく最高の古い方法として説明した最も単純な形式であり、およびExcel 2003のものと同様に、クエリの結果とコントロールを与え、2000年この研究では、あなたのコードで何が起きているのか、また何が異なるのかを理解していると思います。コアビットはここにある:
With ActiveWorkbook.Connections("RISCTEST - ParmPass").ODBCConnection
.CommandText = "call K9751DB.SP_GETRTSDB_BYDBTSNOPTLIKEDTTM('" & LPARSSID & "', '" & DBNAME & "', '" & TSNAME & "','2017-10-01 23:25:59.999999','2')"
ActiveWorkbook.Connections("RISCTEST - ParmPass").Refresh
End With
は(大規模な再分割の私のスタイルで)このように、おそらくクリーンアップ:今は見て
Dim wb As Excel.Workbook
Dim conns As Excel.Connections
Dim conn As Excel.WorkbookConnection
Dim odbc As Excel.ODBCConnection
Dim connName As String
Dim connCmdText As String
Dim spName As String
Dim p1 As String
Dim p2 As String
Dim p3 As String
Dim p4 As String
Dim p5 As String
'Set up the parameter strings for everything.
connName = "RISCTEST - ParmPass"
spName = "K9751DB.SP_GETRTSDB_BYDBTSNOPTLIKEDTTM"
p1 = LPARSSID
p2 = DBNAME
p3 = TSNAME
p4 = "2017-10-01 23:25:59.999999"
p5 = "2"
'I use this trick to make quoted-strings within quoted-strings more
'readable. It's more lines of code, but easy to make with copy &
'paste, and when your eyes get blurry and tired and crossed and those
'double and single quotes start to look like triple single quotes
'and you can't tell quadruple single-quotes from double double-quotes,
'it can be a life saver. =-)
'This is the actual command.
connCmdText = "call spname('p1','p2','p3','p4','p5')"
'Now replace all the parameter codes with the real data. Be careful when
'choosing the names of the codes so they don't conflict with any correct
'strings already in the command string, or mayhem will result. Use goofy
'punctuation to make them more unique if necessary.
connCmdText = VBA.Replace(connCmdText, "spname", spName, , , vbTextCompare)
connCmdText = VBA.Replace(connCmdText, "p1", p1, , , vbTextCompare)
connCmdText = VBA.Replace(connCmdText, "p2", p2, , , vbTextCompare)
connCmdText = VBA.Replace(connCmdText, "p3", p3, , , vbTextCompare)
connCmdText = VBA.Replace(connCmdText, "p4", p4, , , vbTextCompare)
connCmdText = VBA.Replace(connCmdText, "p5", p5, , , vbTextCompare)
'Now to the business.
Set wb = Excel.ActiveWorkbook
Set conns = wb.Connections
Set conn = conns.Item(connName)
Set odbc = conn.ODBCConnection
odbc.CommandText = connCmdText
conn.Refresh
'The with block wasn't even needed. (I think.)
、私はQTが表示されません。あなたのコードに、OPには含まれていないものがありますか?あなたが投稿したコードがすべてのものであれば、Excelにクエリ結果をどこに置くべきかは分かりません。しかし、何か著しく異なるものがなければ、あなたは、あなたが望むものを得るために、異なるコードのためのいくつかの仮定を可能にするのに十分なものを示しました。
この問題を理解するために私が今日試したDB2システムの実際の作業手順は次のとおりです。 Sheet1のA1に基本的なExcel 2003スタイルのクエリ結果を掲載します。私は、匿名性のためにサーバーのユーザー資格情報とIPだけを消し去りました。これは、Excel VBAでのクエリの最も基本的な実装です。独立QTです。
Sub TestQT()
Dim connStr As String
Dim connCmdText As String
Dim destRangeAddr As String
Dim ws As Excel.Worksheet
Dim qts As Excel.QueryTables
Dim qt As Excel.QueryTable
Dim destRangeRng As Excel.Range
'Set up the connection string and other variables for the query.
destRangeAddr = "A1"
connCmdText = "SELECT * FROM VIPDTAB.BEERXT"
connStr = _
"ODBC;" & _
"DRIVER={iSeries Access ODBC Driver};" & _
"UID=********;" & _
"PWD=********;" & _
"SIGNON=1;" & _
"QRYSTGLMT=-1;" & _
"PKG=QGPL/DEFAULT(IBM),2,0,1,0,512;" & _
"LANGUAGEID=ENU;" & _
"DFTPKGLIB=QGPL;" & _
"DBQ=VIPDTAB;" & _
"SYSTEM=***.***.***.***;" & _
"FILEDSN=NOTHING;"
'In experiments I found FILEDSN doesn't need to be anything, it can
'simply be FILEDSN=DUMMY, if you wish to use a DSN-less connections,
'as I do. Also, obviously the password is visible and as such is a
'security issue.
'Define the sheet.
Set ws = ActiveSheet
'Clean up the sheet. Useful if the query is run repeatedly, and to avoid the
'runtime error that says "overlapping pivot table".
ws.Cells.Clear
ws.Cells.ColumnWidth = 8
'Now to business.
Set destRangeRng = ws.Range(destRangeAddr) 'Range object to paste the data.
Set qts = ws.QueryTables 'The QT collection.
Set qt = qts.Add(connStr, destRangeRng, connCmdText) 'Create the query
'Now run it. 'False makes Excel lock up during long queries, so True is best.
qt.Refresh BackgroundQuery:=True
End Sub
ここで、これらのアイデアをまとめて問題を解決してください。最後の数行を除いて、すべてがほぼ同じです。もちろん私はあなたのシステムではないので、私はこれをテストする方法がありませんが、私はそれにデバッガを実行して、打ち明けのタイプミスをキャッチしました。だから、私はあなたがより多くの助けが必要な場合は、バック叫ぶ:
Sub TestQuery2()
Dim wb As Excel.Workbook
Dim ws As Excel.Worksheet
Dim qts As Excel.QueryTables
Dim qt As Excel.QueryTable
Dim conns As Excel.Connections
Dim conn As Excel.WorkbookConnection
Dim destRangeObj As Excel.Range
Dim destRangeTxt As String
Dim connName As String
Dim connDesc As String
Dim connStr As String
Dim spName As String
Dim connCmdText As String
Dim p1 As String
Dim p2 As String
Dim p3 As String
Dim p4 As String
Dim p5 As String
connName = "RISCTEST - ParmPass"
connDesc = "" 'set the description as/if desired
connStr = _
"DRIVER={IBM DB2 ODBC DRIVER};" & _
"UID=k9751x1;" & _
"PWD=********;" & _
"MODE=SHARE;" & _
"DBALIAS=RISCTEST;"
destRangeTxt = "$A$1"
'Set up the procedure call by replacing the parameters.
'It's much more readable than quotes within quotes.
connCmdText = "call spname('p1','p2','p3','p4','p5')"
spName = "K9751DB.SP_GETRTSDB_BYDBTSNOPTLIKEDTTM"
p1 = Sheets("RTSbyDBTSDTE").Range("B2").Value
p2 = Sheets("RTSbyDBTSDTE").Range("B3").Value
p3 = Sheets("RTSbyDBTSDTE").Range("B4").Value
p4 = "2017-10-01 23:25:59.999999"
p5 = "2"
'Replace all the parameters.
connCmdText = VBA.Replace(connCmdText, "spname", spName, , , vbTextCompare)
connCmdText = VBA.Replace(connCmdText, "p1", p1, , , vbTextCompare)
connCmdText = VBA.Replace(connCmdText, "p2", p2, , , vbTextCompare)
connCmdText = VBA.Replace(connCmdText, "p3", p3, , , vbTextCompare)
connCmdText = VBA.Replace(connCmdText, "p4", p4, , , vbTextCompare)
connCmdText = VBA.Replace(connCmdText, "p5", p5, , , vbTextCompare)
'Define the worksheet and destination.
Set ws = ActiveSheet
Set destRangeObj = ws.Range(destRangeTxt)
'Clean up the sheet. Useful if query is run repeatedly. If used as
'such, the .Clear has to happen before the .Add method, or a runtime
'error will ocurr due to the old query blocking the new one. I didn't
'save the message, it was something about "pivot table overlap".
ws.Cells.Clear 'wipe all values, formatting, conections, and queries
ws.Cells.EntireColumn.ColumnWidth = 8
'Something I noticed that's different between an LO/QT and independent-QT,
'with an LO/QT, the connection is attached to the table, literally. So the .Clear
'may not delete the connection if it was created by an independent-QT. The following
'bit of code should take care of that, by looping through the connections and
'deleting any connection that already exists with the same name.
Set wb = ws.Parent
Set conns = wb.Connections
For Each conn In conns
If conn.Name = connName Then
conn.Delete
Exit For
End If
Next
'Now the business.
Set qts = ws.QueryTables
Set qt = qts.Add(connStr, destRangeObj, connCmdText)
'Now both the query and connection have been created. The connection name, which
'appears in the Workbook Connections window, needs to be set. When the QT is created
'in the .Add procedure above, the connection is also created, but there's no way to
'specify its name, so it just uses the name "Connection". But that can be changed
'after the fact, as can the connection description, if desired.
Set conn = qt.WorkbookConnection
conn.Name = connName
conn.Description = connDesc
'And finally, the fireworks:
qt.Refresh True
End Sub
私はSQL Serverストアドプロシージャを呼び出すためにコードを使ってみましたが(私はDB2をテスト用に利用できませんでした)、うまくいきました。 –