Можно ли использовать Access VBA для определения наличия в таблице макроса данных?
Есть ли способ определить через VBA, содержит ли таблица Access макрос данных или нет? У меня есть макросы данных в большинстве моих таблиц, но мой код не выполняется, если он встречает таблицу без нее.
Я не получаю сообщение об ошибке. Вместо этого код продолжает работать так, как будто он находится в бесконечном цикле, но я вынужден заставить Access выйти из программы.
В частности, я пытаюсь сохранить все свои таблицы и макросы данных, чтобы я мог использовать (недокументированную) функцию LoadFromText, чтобы создать их позже.
Я выделил проблему в моем примере кода ниже с помощью ** BUG **.
For Each td In db.TableDefs
If Left(td.Name, 4) <> "MSys" Then
'Save the table as a text file.
DoCmd.TransferText acExportDelim, , td.Name, sExportLocation & "Table_" & td.Name & ".txt", True
'Save the table's data macro as an XML file.
'** BUG **: If a table doesn't have a data macro, Access freezes/starts infinite loop.
Application.SaveAsText acTableDataMacro, td.Name, sExportLocation & "Table_" & td.Name & "_DataMacro.xml"
End If
Next td
Я предполагаю, что мне нужен некий вложенный оператор If, который сначала проверяет, существует ли в таблице макрос данных. Я не уверен, как написать это, хотя.
Спасибо людям, которые указали функции SaveAsText и LoadFromText в другом посте SO. Эти функции, кажется, имеют большой потенциал.
2 ответа
Вы можете использовать простой запрос, чтобы указать, есть ли в таблице макрос данных:
SELECT [Name] FROM MSysObjects WHERE Not IsNull(LvExtra) and Type =1
Этот макрос можно применить к коду VBA в вопросе следующим образом:
For Each td In db.TableDefs
If Left(td.Name, 4) <> "MSys" Then
'Save the table as a text file.
DoCmd.TransferText acExportDelim, , td.Name, sExportLocation & _
"Table_" & td.Name & ".txt", True
'Define a recordset to determine if the table has a data macro.
sql = "SELECT [Name] FROM MSysObjects WHERE Not IsNull(LvExtra) and " & _
"Type = 1 and [Name] = '" & td.Name & "'"
Set rst = db.OpenRecordset(sql, dbOpenSnapshot)
'If the table has a data macro, save the data macro as an XML file.
If rst.RecordCount <> 0 Then
Application.SaveAsText acTableDataMacro, td.Name, sExportLocation & _
"Table_" & td.Name & "_DataMacro.xml"
End If
'Close the recordset and clear its variable.
If Not rst Is Nothing Then
rst.Close
Set rst = Nothing
End If
End If
Next td
Кредит идет к сообщению на UtterAccess и ответу @Scotch на вопрос о SO, который ссылается на сообщение UtterAccess.
Чтобы увидеть, содержит ли база данных макросы или нет, вы можете использовать документированные методы из DAO. Вот модифицированный пример с https://msdn.microsoft.com/en-us/library/office/ff191764.aspx:
Sub ContainerObjectX()
Dim dbsNorthwind As Database
Dim ctrLoop As Container
Dim prpLoop As Property
Dim docItem As Document
' Set dbsNorthwind = OpenDatabase("Northwind.mdb")
Set dbsNorthwind = CurrentDb
With dbsNorthwind
' Enumerate Containers collection.
For Each ctrLoop In .Containers
Debug.Print "Properties of " & ctrLoop.Name _
& " container"
' Enumerate Properties collection of each
' Container object.
For Each prpLoop In ctrLoop.Properties
Debug.Print " " & prpLoop.Name _
& " = "; prpLoop
Next prpLoop
For Each docItem In ctrLoop.Documents
Debug.Print " docItem.Name = "; docItem.Name
Next docItem
Next ctrLoop
.Close
End With
End Sub
Так что вам просто нужно проверить документы в контейнере "Сценарии".
Мой оригинальный ответ: я думаю, что вы можете использовать ExportXML и ImportXML, это гораздо более мощный и способный делать экспорт и импорт всех объектов доступа. Пример:
ExportXML acExportTable, "tblMain", CM_GetDBPath() & "AccessFunc_Tbl.xml" _
, CM_GetDBPath() & "AccessFunc_TblShema.xml", CM_GetDBPath() & "AccessFunc_Tbl.xsl" _
, "Images", , acEmbedSchema
....
ImportXML CM_GetDBPath() & "AccessFunc_Tbl.xml", acAppendData
Полный пример здесь: http://5codelines.net/wp-content/uploads/xml_1_sampe.rar
Также вы можете использовать библиотеку ADODB.
Public Function EportTblToXml(ByVal imTblFrom As String _
, ByVal imFileTo As String)
Dim rstData As ADODB.Recordset
Dim cnn As ADODB.Connection
Set cnn = CurrentProject.Connection
Set rstData = New ADODB.Recordset
rstData.Open "SELECT * FROM " & imTblFrom, cnn _
, adOpenKeyset, adLockOptimistic
Call SaveRstToXml(rstData, imFileTo)
rstData.Close
End Function
Public Function LoadXmlToRst(ByVal stFileName As String) As ADODB.Recordset
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
rst.Open stFileName
Set LoadXmlToRst = rst
End Function