2009-10-20 8 views
6

Więc chciałbym skopiować połączoną tabelę do lokalnej w kodzie, strukturze i danych w MS Access 2003.Jak skopiować połączoną tabelę do lokalnej tabeli w programie Ms Access programowo?

Kod będący: VBA lub C#. Lub cokolwiek innego w tej sprawie ..

AKTUALIZACJA: Chcę zachować strukturę kopii i zachowanie danych z dostępu ms, aby zachować Klucze podstawowe. Jeśli skopiujesz połączoną tabelę, możesz ją wkleić jako "strukturę i dane (tabela lokalna)" Chodzi o to, że chcę osiągnąć w kodzie.

Odpowiedz

6

Rozumiem, że DAO nie obsługuje typu danych dziesiętnych, ale robi to ADOX. Oto zaktualizowana procedura, która zamiast tego używa ADOX do skopiowania schematu do nowej tabeli.

Jeden interesujący przedmiot: dostawca OLEDB dla Jet sortuje kolumny w kolejności alfabetycznej, a nie porządkowej, jak wyjaśniono in this KB article. Nie przejmowałem się utrzymaniem pozycji porządkowej, ale może być, w takim przypadku możesz zaktualizować tę procedurę do swoich potrzeb.

Aby kod wersji ADOX działał, konieczne będzie ustawienie odwołania do Microsoft ADO Ext. 2.x dla DDL i bezpieczeństwa (gdzie x = numer wersji, użyłem 2.8, aby przetestować tę procedurę). Będziesz także potrzebował odniesienia do ADO.

Public Sub CopySchemaAndData_ADOX(ByVal sourceTableName As String, ByVal destinationTableName As String) 
On Error GoTo Err_Handler 

Dim cn As ADODB.Connection 
Dim cat As ADOX.Catalog 
Dim sourceTable As ADOX.Table 
Dim destinationTable As ADOX.Table 

Set cn = CurrentProject.Connection 
Set cat = New ADOX.Catalog 
Set cat.ActiveConnection = cn 

Set destinationTable = New ADOX.Table 
destinationTable.Name = destinationTableName 

Set sourceTable = cat.Tables(sourceTableName) 

Dim col As ADOX.Column 
For Each col In sourceTable.Columns 
    Dim newCol As ADOX.Column 
    Set newCol = New ADOX.Column 

    With newCol 
     .Name = col.Name 
     .Attributes = col.Attributes 
     .DefinedSize = col.DefinedSize 
     .NumericScale = col.NumericScale 
     .Precision = col.Precision 
     .Type = col.Type 
    End With 

    destinationTable.Columns.Append newCol 
Next col 

Dim key As ADOX.key 
Dim newKey As ADOX.key 

Dim KeyCol As ADOX.Column 
Dim newKeyCol As ADOX.Column 
For Each key In sourceTable.Keys 
    Set newKey = New ADOX.key 
    newKey.Name = key.Name 
    For Each KeyCol In key.Columns 
     Set newKeyCol = destinationTable.Columns(KeyCol.Name) 
     newKey.Columns.Append (newKeyCol) 
    Next KeyCol 

    destinationTable.Keys.Append newKey 
Next key 

cat.Tables.Append destinationTable 

'Finally, copy data from source to destination table 
Dim sql As String 
sql = "INSERT INTO " & destinationTableName & " SELECT * FROM " & sourceTableName 
CurrentDb.Execute sql 

Err_Handler: 
    Set cat = Nothing 
    Set key = Nothing 
    Set col = Nothing 
    Set sourceTable = Nothing 
    Set destinationTable = Nothing 
    Set cn = Nothing 

    If Err.Number <> 0 Then 
     MsgBox Err.Number & ": " & Err.Description, vbCritical, Err.Source 
    End If 
End Sub 

Oto oryginalna procedura DAO

Public Sub CopySchemaAndData_DAO(SourceTable As String, DestinationTable As String) 
On Error GoTo Err_Handler 

Dim tblSource As DAO.TableDef 
Dim fld As DAO.Field 

Dim db As DAO.Database 
Set db = CurrentDb 

Set tblSource = db.TableDefs(SourceTable) 

Dim tblDest As DAO.TableDef 
Set tblDest = db.CreateTableDef(DestinationTable) 

'Iterate over source table fields and add to new table 
For Each fld In tblSource.Fields 
    Dim destField As DAO.Field 
    Set destField = tblDest.CreateField(fld.Name, fld.Type, fld.Size) 
    If fld.Type = 10 Then 
     'text, allow zero length 
     destField.AllowZeroLength = True 
    End If 
    tblDest.Fields.Append destField 
Next fld 

'Handle Indexes 
Dim idx As Index 
Dim iIndex As Integer 
For iIndex = 0 To tblSource.Indexes.Count - 1 
    Set idx = tblSource.Indexes(iIndex) 
    Dim newIndex As Index 
    Set newIndex = tblDest.CreateIndex(idx.Name) 
    With newIndex 
     .Unique = idx.Unique 
     .Primary = idx.Primary 
     'Some Indexes are made up of more than one field 
     Dim iIdxFldCount As Integer 
     For iIdxFldCount = 0 To idx.Fields.Count - 1 
     .Fields.Append .CreateField(idx.Fields(iIdxFldCount).Name) 
     Next iIdxFldCount 
    End With 

    tblDest.Indexes.Append newIndex 
Next iIndex 

db.TableDefs.Append tblDest 

'Finally, copy data from source to destination table 
Dim sql As String 
sql = "INSERT INTO " & DestinationTable & " SELECT * FROM " & SourceTable 
db.Execute sql 

Err_Handler: 
    Set fld = Nothing 
    Set destField = Nothing 
    Set tblDest = Nothing 
    Set tblSource = Nothing 
    Set db = Nothing 

    If Err.Number <> 0 Then 
     MsgBox Err.Number & ": " & Err.Description, vbCritical, Err.Source 
    End If 
End Sub 
+0

Tx man! Powiedz mi, czy wiesz, dlaczego tak oczywiste rzeczy (przechowywanie kluczy podstawowych) nie są obsługiwane z importowanymi danymi w dostępie? – Peter

+0

Nie mam pojęcia, zwłaszcza biorąc pod uwagę, jak długi był dostęp. Można by pomyśleć, że jest to opcja przynajmniej ... –

+0

Nie działa dla wartości dziesiętnych Obawiam się ... – Peter

0

spróbować docmd.CopyObject lub docmd.TransferDatabase

+1

nie będzie to tylko skopiowanie tabeli połączonej zamiast dokonać lokalnej tabeli? – Peter

+0

Tak, z mojego doświadczenia, działa Docmd.CopyObject "dest_table", acTable, "source_table" gdzie tabela źródłowa jest połączoną tabelą, tworzy tylko kopię łącza do tej samej tabeli ... – avguchenko

-1

Tworzenie kwerendy i wykonywać to

SELECT * INTO MyNewTable FROM LinkedTableName

w VBA można zrobić

docmd.runsql "SELECT * INTO MyNewTable FROM LinkedTableName"

Aby zachować strukturę ty musiałby wykonać DoCmd.TransferDatabase acImport

+1

Zobacz aktualizację proszę, to zapytanie nie zachowuje kluczy podstawowych. – Peter

+0

Nie, import również traci klucze z widoczną informacją – Peter

Powiązane problemy