2014-07-11 1 views
0

나는이 문제에 대해 잠시 생각을 해왔으며 해결책이 있는지 궁금해하고있었습니다.Excel 시트에서 WHERE 조건을 사용하여 Access 데이터베이스에 필드를 삽입하는 방법

그래서 나는이 칼럼과 R1라는 테이블이 있습니다 [학과]와 [DepartmentQV] Access에서, [부서] 열은 값으로 몇 가지 필드가 있지만 [DepartmentQV] 열은

또한 비어 엑셀에 [Department] 열과 [DepartmentQV] 열이있는 스프레드 시트가 있어야합니다. [Department] 열은 Access의 열과 동일하지만 [DepartmentQV] 열에는 값이 있습니다.

내가 원하는 것은 ADODB와 SQL을 사용하여 [DepartmentQV] 값을 Excel 시트에서 [Department] 값이 일치하는 Access 데이터베이스로 가져 오는 것입니다.

불행히도, 이것은 전혀 작동하지 않습니다. "하나 이상의 매개 변수에 필요한 값이 없습니다."라는 동일한 오류가 계속 발생하여 완전히 의아해합니다. 어떤 도움을 주시면 감사하겠습니다! 이 시간을내어 읽어 주셔서 감사합니다!

보다도, 커트

여기에 지금까지 내 코드입니다!

lastRow = ActiveWorkbook.ActiveSheet.Range("B" & ActiveWorkbook.ActiveSheet.Rows.Count).End(xlUp).Row 

    Set cn = CreateObject("ADODB.Connection") 
    dbPath = glob_sdbPath 
    dbWb = Application.ActiveWorkbook.FullName 
    dbWs = ActiveWorkbook.ActiveSheet.Name 
    scn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath 
    dsh = "[" & Application.ActiveSheet.Name & "$B2:C" & lastRow & "]" 
    cn.Open scn 

    sSql = "INSERT INTO R1([Department_QV])" 
    sSql = sSql & " SELECT [Spoilage] FROM [Excel 12.0;HDR=YES;DATABASE=" & dbWb & "]." & dsh & " WHERE " & dsh & ".[Department] = R1.[Department]" 

    cn.Execute sSql 
+0

B2 : Cx 범위에서 헤더 행을 생략 하시겠습니까? 이 경우 레코드 세트에는 원하는 이름이 없습니다. 또한 SQL이 이상합니다. 새 행을 INSERT하거나 기존 행을 UPDATE하려고합니까? – VBlades

+0

헤더 행은 실제로 B2 : C2에 있으며 실제로 기존 행을 업데이트하려고합니다. 난 항상 adodb 및 액세스와 함께 업데이 트를 사용하는 데 문제가 있었습니까, 당신은 당신이 할 것이라고 내가 바라는 것을 구현할 수있는 방법을 알지 못했을까요? 아직도 운이 아직까지 한숨 – bluecat

답변

1

여기서 문제는 ADO를 사용하여 Access와 Excel간에 업데이트가 발생하는 것입니다.

가 신경 끄시는 액세스 테이블을 Excel로 연결되지
"Run-time error '-2147467259 (80004005)': 
You cannot edit this field because it resides in a linked Excel spreadsheet. The ability to edit data in a linked Excel spreadsheet has been disabled in this Access Release." 

, 나는이에 대한 해결책을 찾을 수 없습니다 : 내가 액세스 테이블에 대해 파생 엑셀 테이블을 가입하고 업데이트를 수행 INNER하려고 할 때, 나는 오류가 발생했습니다 저 밖에. 대신 Access에서 임시 테이블로 Excel 데이터를 밀어 넣고 R1 및 임시 테이블에 대해 업데이트를 실행하기로 결정했습니다. 업데이트를 수행하는 다른 방법은 Excel 테이블 하나, 다른 Access 테이블 하나, 다른 레코드 테이블 하나를 검색하여 두 개의 레코드 세트를 여는 것이 었습니다.

는 (. I는 Microsoft ActiveX 데이터 마이크로 소프트 ADOX 내선 DDL 및 보안 그래서 인텔리있을 것입니다 2.8뿐만 아니라 2.8 개체 라이브러리를 참조 당신이 좋아하지만 당신은 객체를 생성 할 수 있습니다..) :

Public Sub ExcelToAcessUpdate() 
On Error GoTo ErrorHandler 

    Dim cn As New ADODB.Connection 
    Dim rstTables As New ADODB.Recordset 
    Dim cat As New ADOX.Catalog 

    Dim dbWb As String 
    Dim dbWs As String 
    Dim dsh As Variant 
    Dim lastRow As Integer 

    Dim dbPath As String 
    Dim scn As String 
    Dim sTempTable As String 
    Dim sSql As String 

    dbWb = Application.ActiveWorkbook.FullName 
    dbWs = ActiveWorkbook.ActiveSheet.Name 
    dsh = "[" & Application.ActiveSheet.Name & "$B2:C" & lastRow & "]" 
    lastRow = ActiveWorkbook.ActiveSheet.Range("B" & ActiveWorkbook.ActiveSheet.Rows.Count).End(xlUp).Row 

    dbPath = glob_sdbPath 
    scn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath 

    'This is the name of the temp table in Access 
    'we will use to hold our Excel data. 
    sTempTable = "tblMyExcelTemp" 

    cn.Open scn 

    'Make the ADO connection get a recordset of tables in database. 
    Set rstTables = cn.OpenSchema(adSchemaTables) 

    'If temp table we want to use already exists in db, delete it. 
    With rstTables 
     Do Until .EOF 
      If .Fields("TABLE_TYPE") = "TABLE" And _ 
       .Fields("TABLE_NAME") = sTempTable Then 
        Set cat.ActiveConnection = cn 
        cat.Tables.Delete sTempTable 

        Exit Do 
      End If 

      .MoveNext 
     Loop 
    End With 

    'Get all our Excel data and push it into temp table. 
    sSql = "SELECT [Department], [Spoilage] INTO " & sTempTable & " " & _ 
      "FROM [Excel 12.0;HDR=YES;DATABASE=" & dbWb & "]." & dsh 

    cn.Execute sSql 

    'Update R1 using inner join against Excel Temp table. 
    sSql = "UPDATE R1 INNER JOIN " & sTempTable & " e ON R1.[Department] = e.[Department] " & _ 
      " SET Department_QV = e.[Spoilage]" 

    cn.Execute sSql 

ExitMe: 
    If cn Is Nothing = False Then 
     If cn.State <> adStateClosed Then 
      cn.Close 
     End If 
    End If 

    Set cat = Nothing 
    Set rstTables = Nothing 
    Set cn = Nothing 

    Exit Sub 
ErrorHandler: 
    'Lazy error handling, need to go through cn.Errors collection, actually. 
    MsgBox Err.Number & ": " & Err.Description 
    GoTo ExitMe 

End Sub 

저는 임시 테이블 솔루션에 대한 열렬한 팬이 아닙니다. 그러나 이러한 일을 많이해야하는 경우 작동하며 패러다임이 될 수 있습니다. 잘하면 그것은 당신을 위해 작동합니다. 레코드 세트를 사용하는 커서 기반 솔루션은 너무 비효율적이었을 것입니다.하지만 그렇게 할 수도 있습니다.

+0

정말이 철저한 대안을 가져 주셔서 감사합니다! 나는 심지어 당신의 방법을 통해 adodb와 함께 몇 가지 더 깔끔한 트릭을 배웠다! – bluecat

+0

@bluecat : 대단히 환영합니다. 그것이 당신을 도울 수 있기를 바랍니다. 적어도 당신을 더 나은 길로 인도 할 수 있기를 바랍니다. – VBlades