Это на самом деле кажется 2 немного разными вопросами, чем те, которые были заданы, если я правильно его читаю: (1) Можете ли вы вставить двоичный файл в базу данных JET/ACE? и (2) Можете ли вы вызвать методы из .NET DLL из MS-Access?
- Да, вы можете встраивать двоичный файл в базу данных JET/ACE. Мой предпочтительный способ сделать это - прочитать файл как двоичный и кодировать как base64 в поле Memo.
Во-первых, вам нужно прочитать в двоичном файле в массив байтов. Это можно сделать с помощью Open
или с помощью объекта ADODB.Stream
. Затем вы кодируете массив байтов как строку Base64, и, наконец, вы записываете эту строку в таблицу. Чтобы экспортировать двоичный файл, вы делаете обратное.
Вот функции для преобразования массива в базе 64 (Source):
'Requires reference to Microsoft XML v3.0
Private Function EncodeBase64(ByRef arrData() As Byte) As String
Dim objXML As MSXML2.DOMDocument
Dim objNode As MSXML2.IXMLDOMElement
' help from MSXML
Set objXML = New MSXML2.DOMDocument
' byte array to base64
Set objNode = objXML.createElement("b64")
objNode.dataType = "bin.base64"
objNode.nodeTypedValue = arrData
EncodeBase64 = objNode.Text
' thanks, bye
Set objNode = Nothing
Set objXML = Nothing
End Function
Private Function DecodeBase64(ByVal strData As String) As Byte()
Dim objXML As MSXML2.DOMDocument
Dim objNode As MSXML2.IXMLDOMElement
' help from MSXML
Set objXML = New MSXML2.DOMDocument
Set objNode = objXML.createElement("b64")
objNode.dataType = "bin.base64"
objNode.Text = strData
DecodeBase64 = objNode.nodeTypedValue
' thanks, bye
Set objNode = Nothing
Set objXML = Nothing
End Function
И вот примеры того, как использовать эти Base64 функции импорта и экспорта двоичного файла в поле Memo, используя ADODB.Stream
объект:
Function ImportBinary()
'Requires a reference to ActiveX Data Objects 2.8 or higher
Dim InputStream As ADODB.stream
Dim FileBytes() As Byte
Set InputStream = New ADODB.stream
InputStream.Type = adTypeBinary
InputStream.Open
InputStream.LoadFromFile ("A:\Binary\File\To\Import.dll")
FileBytes = InputStream.Read()
With CurrentDb().TableDefs("TableWithMemoField").OpenRecordset
.AddNew
!MemoField.Value = EncodeBase64(FileBytes)
.Update
.Close
End With
InputStream.Close
End Function
Function ExportBinary()
Dim OutputStream As ADODB.stream
Set OutputStream = New ADODB.stream
OutputStream.Type = adTypeBinary
OutputStream.Open
With CurrentDb().TableDefs("TableWithMemoField").OpenRecordset
OutputStream.Write DecodeBase64(!MemoField.Value)
.Close
End With
OutputStream.SaveToFile "A:\Binary\File\To\Export.dll"
OutputStream.Close
End Function
Кроме того, вы также можете вставить файл (ы) в OLE полей, или, в последних версиях Access также есть поле «Приложение». Я считаю, что это возможно.
- Да, можно вызвать методы из .NET DLL - см. here. В основном вы занимаетесь хостингом .NET runtime в Access.
Ограничение на то, что вы можете использовать только среду .NET 2.0 или 3.5 - несмотря на то, что на связанной странице говорится, что вы можете использовать 4.0. Насколько я знаю, нет простого способа размещения среды .NET 4.0+ в VBA. Если вы попытаетесь вызвать DLL 4.0+, вы получите сообщение об ошибке «сборка более новая, чем среда выполнения».
Да, вам также необходимо использовать его на машине, на которой установлены версии 2.0 и/или 3.5.
Кроме того, он не будет загружать DLL непосредственно из общего сетевого ресурса. Это ограничение .NET framework, которое можно преодолеть (link), но я не уверен, что это можно сделать при размещении DLL в Access.
Чтобы использовать «встроенную» DLL, вам необходимо экспортировать ее из базы данных, прежде чем использовать ее; хорошим местом будет временная папка пользователя.
EDIT: Относительно точки (2) - Я ранее писал, что вам не нужно выставлять свой класс C# в качестве COM, однако после тестирования я понял, что это неверно.Вам нужно объявить свой класс атрибутом [COMVisible(true)]
(или реализовать интерфейс IDispatch), чтобы VBA правильно создавал экземпляр вашего класса - иначе CreateInstanceFrom
ничего не вернет.
Это, кажется, исключительно плохое решение любой проблемы, которая у вас есть. Почему бы вам не спросить о своей реальной проблеме? – nvoigt
Вы можете сохранить слово или .exe или .dll внутри Access. Таким образом, при запуске Access вы наверняка можете проверить наличие DLL, а если не найти, вытащите их из локальной таблицы в Access и поместите DLL в том же каталоге, что и ваше приложение. Однако, как отмечалось до этого времени, вы вытаскиваете файлы .net (COM), они не могут использоваться Access. И в большинстве случаев вам также придется регистрировать такие COM-объекты, прежде чем их можно будет использовать - это означает, что пользователям потребуется достаточно прав для регистрации COM-объектов, если не используется подход «бок о бок» .net. –