2017-11-07 15 views
0

vbaについては非常に時折アマチュアですが、これはまっすぐであるはずですか?2回目のパススルーでエラーが発生し、オラクルからデータをコピーするとエラーが発生する

oracle dbの各表の内容をExcelファイルの別々のタブにコピーしようとしています。コードは、Excelファイルの最初のタブのリストから必要なテーブルの名前を取得し、配列に格納します。私はその後、各テーブルの新しいタブを作成し、データをコピーする配列をループしようとしています。このコードは、For Eachループを最初に通過するときに機能しますが、2番目のテーブルのrsを開こうとする箇所では常に失敗します。ループの内側と外側でレコードセットの開閉をさまざまな方法で試してみましたが、無駄です。データをコピーした後にrsをクローズしないと、rs.Open(sSQL)に接続したときにクローズされていないというエラーが表示されます。接続を閉じると、同じエラーが発生します。ポイントは....

Sub Ora_Connection() 
Dim con As ADODB.Connection 
Dim rs As ADODB.Recordset 
Dim query As String   ' a string to contain the db connection data 
Dim myTABLELIST As Variant   ' a variant to contain the list of oracle tables that contain data that we want to copy to excel 
Dim lArr As Variant 


' copy contents of TABLELIST into vb array 
myTABLELIST = Worksheets("TABLE_LIST").ListObjects("TABLELIST").DataBodyRange.Value 


' add a tab for every table in list 
For Each lArr In myTABLELIST 

     ' connect to oracle db 
     Set con = New ADODB.Connection 
     con.CursorLocation = adUseClient ' avoid error 3705 - doesn't do anything 
     Set rs = New ADODB.Recordset 
     '---- Replace HOST and COONECT_DATA with values for the db you are connecting to 
     strCon = "Driver={Microsoft ODBC for Oracle}; " & _ 
     "CONNECTSTRING=(DESCRIPTION=" & _ 
     "(ADDRESS=(PROTOCOL=TCP)" & _ 
     "(HOST=myHost)(PORT=1521))" & _ 
     "(CONNECT_DATA=(SID=mySID))); uid=myUID; pwd=myPWD;" 
     '--- Open the above connection string. 
     con.Open (strCon) 
     '--- Now connection is open and you can use queries to execute them. 
     '--- It will be open till you close the connection 

     ' make the connection able to travel only forwards through the recordset, so the query runs faster 
     rs.CursorType = adOpenForwardOnly 



    Sheets.Add After:=Sheets(Sheets.Count) 
    ActiveSheet.Name = lArr 

    'creat SQl statement that uses table name in array 
    sSQL = "SELECT * FROM " & lArr 
    'If Not rs.State = adStateClosed Then 
    'MsgBox "The recordset is already open" 
    'End If 
    rs.Open (sSQL), con 
    Worksheets(lArr).Activate 
    ' copy column header from source data into row 1 
    For iCols = 0 To rs.Fields.Count - 1 
    ActiveSheet.Cells(1, iCols + 1).Value = rs.Fields(iCols).Name 
    Next 
    ' copy all data rows from source data into range starting at A2 
    ActiveSheet.Range(ActiveSheet.Cells(1, 1), _ 
    ActiveSheet.Cells(1, rs.Fields.Count)).Font.Bold = True 
    ActiveSheet.Range("A2").CopyFromRecordset rs 


Next lArr 



' clear recordset and close connection 
Set rs = Nothing 
Set con = Nothing 

End Sub 
+0

は、すべてのコメントコードを削除してください。それは疑問に役に立たず、読みにくいです。また、オラクルの接続文字列情報を投稿から削除することをお勧めします。 –

+0

コードを正確に(接続情報のみを変更して)Excelバージョン14.0.7015.1000にコピーし、Microsoft ActiveX Data Objects 6.1ライブラリへの参照を追加し、2行の「TABLELIST」テーブルを含む「TABLE_LIST」ワークシートを作成し、 。 2つのテーブルのすべてのデータを作成したワークシートに抽出しました。 – TurtlesAllTheWayDown

+0

コメント付きのコードについて申し訳ありません - 前に試したことを表示しようとしていました。私のエクセルは14.0.7184.5000です - それが問題であるのを見ることができませんか?私はまたあなたが参照するのと同じvba参照を使用しています。 – clanmac

答えて

0

これは動作するはずです:

Sub Ora_Connection() 

    Dim con As ADODB.Connection 
    Dim rs As ADODB.Recordset 
    Dim myTABLELIST As Variant, strCon As String, iCols As Long 
    Dim lArr As Variant, ws As Worksheet, r As Long, wb As Workbook 

    Set wb = ThisWorkbook 

    myTABLELIST = wb.Worksheets("TABLE_LIST").ListObjects("TABLELIST").DataBodyRange.Value 

    Set con = New ADODB.Connection 
    strCon = "yourConnectionInfoHere" 
    con.Open strCon 

    ' add a tab for every table in list 
    For r = 1 To UBound(myTABLELIST, 1) 

     lArr = myTABLELIST(r, 1) 

     Set rs = con.Execute("SELECT * FROM " & lArr) 
     Set ws = wb.Worksheets.Add(after:=wb.Worksheets(wb.Worksheets.Count)) 
     ws.Name = lArr 
     For iCols = 0 To rs.Fields.Count - 1 
      ws.Cells(1, iCols + 1).Value = rs.Fields(iCols).Name 
     Next 
     ws.Cells(1, 1).Resize(1, rs.Fields.Count).Font.Bold = True 
     If Not rs.EOF Then ws.Range("A2").CopyFromRecordset rs 

    Next r 

    Set rs = Nothing 
    con.Close 
    Set con = Nothing 

End Sub 
+0

提案していただきありがとうございます、私のコードと同じポイントになるようです:最初のタブが作成され、[OK]が作成されたが、このステップで2番目の反復ラウンドの外側のループで失敗します: 'Set rs = con.Execute( "SELECT * FROM "&lArr)" - 指定されていないエラーが発生しました... – clanmac

+0

テーブル/ビューが存在し、そのテーブルへの読み取りアクセス権限がありますか?それをリストの先頭に移動すると、最初の反復で失敗しますか? –

+0

はい、私は同じ考えを持っていました。私はリストの表の順序を逆にしましたが、違いはありませんでした。ループコードを別のモジュールに移動して、レコードセットと接続を閉じてループ間に何も設定しないようにしましたが、まだレコードセットを開く2回目の試みで失敗します... – clanmac

関連する問題