2017-11-07 1 views
0

나는 매우 때로는 어리 석었지만 vba에 관해서는 매우 익숙했습니다.오라클에서 데이터를 루프 복사하여 통과하는 두 번째 단계에서 오류가 발생했습니다.

오라클 db의 각 테이블 내용을 Excel 파일의 개별 탭으로 복사하려고합니다. 이 코드는 Excel 파일의 첫 번째 탭에있는 목록에서 원하는 테이블의 이름을 가져 와서 배열에 넣습니다. 그런 다음 배열을 반복하면서 각 테이블에 대한 새 탭을 만들고 데이터를 복사하려고합니다. 이 코드는 For Each 루프를 처음 통과 할 때 작동하지만 두 번째 테이블의 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

모든 주석 코드를 제거하십시오. 그것은 질문에 쓸모없는 것으로 보이고 읽을 수 없게 만듭니다. 또한 게시물에서 Oracle 연결 문자열 정보를 제거하는 것이 좋습니다. –

+0

정확히 (연결 정보 만 변경 한) 코드를 Excel 버전 14.0.7015.1000에 복사하고 Microsoft ActiveX Data Objects 6.1 Library에 대한 참조를 추가하고 2 행의 "TABLELIST"테이블이있는 "TABLE_LIST"워크 시트를 만든 다음 정상적으로 실행했습니다 . 내 두 테이블의 모든 데이터를 생성 된 워크 시트로 추출했습니다. – TurtlesAllTheWayDown

+0

주석 처리 된 코드에 대해 죄송합니다. 이전에 시도한 것을 보여 드리고자했습니다. 내 Excel은 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

제안을 주셔서 감사합니다, 그것은 내 코드와 동일한 지점에 도착하는 것처럼 보입니다 : 첫 번째 탭이 생성되어 생성되었지만이 단계에서 외부 루프 둘째 라운드에서 실패합니다 : 'Set rs = con.Execute ("SELECT * FROM "& lArr)"- 지정되지 않은 오류가 발생했습니다 ... – clanmac

+0

테이블/뷰가 존재하고 해당 테이블/뷰에 대한 읽기 권한이 있습니까? 목록의 맨 위로 이동하면 첫 번째 반복에서 실패합니까? –

+0

네, 같은 생각이 들었습니다. 목록의 순서가 바뀌었고 아무런 차이가 없었습니다. 또한 루프 코드를 다른 모듈로 옮겨서 레코드 세트와 연결을 닫고 루프 사이에 아무 것도 설정하지 않도록 시도했지만 레코드 세트를 여는 두 번째 시도에서 여전히 실패합니다 ... – clanmac

관련 문제