2015-02-05 2 views
2

1) .net dll을 Microsoft Access 데이터베이스에 임베드 할 수 있습니까? 이상적으로는 dll이 실제로 액세스 데이터베이스에 포함되기를 원하므로 누락 될 수 없습니다. 내 액세스 데이터베이스 내에서 몇 가지 API에 액세스해야합니다.Microsoft Access 데이터베이스에 .Net dll을 포함하십시오.

2) 가능한 경우 제한 사항은 무엇입니까? 나는 .net이 설치된 컴퓨터에서 액세스 데이터베이스를 사용해야한다고 가정합니다. 내가 고려해야 할 다른 문제가 있습니까?

+2

그게 무슨 문제라도 예외적으로 나쁜 해결책 인 것 같습니다. 대신 실제 문제에 대해 물어 보시지 않으시겠습니까? – nvoigt

+0

Access 내부에 단어 또는 .exe 또는 .dll을 저장할 수 있습니다. 따라서 Access 시작시 .dll의 존재 여부를 확실히 확인할 수 있습니다. 발견되지 않으면 Access에서 로컬 테이블을 꺼내어 .dll을 응용 프로그램과 동일한 디렉터리에 저장하십시오. 그러나 이러한 시간까지 언급했다. NET (COM) 파일을 끌어 오기, 그들은 Access에서 사용할 수 없습니다. 그리고 대부분의 경우 이러한 COM 객체를 사용하기 전에 등록해야합니다. 즉, side-by-net 접근 방식을 사용할 수없는 경우 COM 객체를 등록 할 수있는 충분한 권한이 필요합니다. –

답변

5

실제로이 질문을 올바르게 읽으면 질문하는 질문과는 약간 다른 질문 인 것 같습니다. (1) JET/ACE 데이터베이스에 이진 코드를 포함 할 수 있습니까? 그리고 (2) MS-Access에서 .NET DLL로부터 메소드를 호출 할 수 있습니까?

  1. 예, 이진 파일을 JET/ACE 데이터베이스에 포함시킬 수 있습니다. 이 작업을 수행하는 기본 방법은 파일을 이진 파일로 읽고 메모 필드에서 base64로 인코딩하는 것입니다.

먼저 이진 파일을 바이트 배열로 읽어야합니다. 이는 Open을 사용하거나 ADODB.Stream 개체를 사용하여 수행 할 수 있습니다. 그런 다음 바이트 배열을 Base64 문자열로 인코딩하고 마지막으로 해당 문자열을 테이블에 씁니다. 바이너리를 내보내려면 그 반대입니다. 여기 가져 오기 및 사용하여 메모 필드에 이진 파일을 내보내려면 그 Base64로 기능을 사용하는 방법의 예는,

'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 

그리고 :

여기 자료 64 (Source)에 바이트 배열을 변환하는 기능입니다 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 필드, 또는 액세스의 최신 버전으로 파일을 포함 할 수있다. 나는 이것을 사용할 수 있다고 믿는다.

  1. 예, .NET DLL에서 메서드를 호출 할 수 있습니다 (here 참조). 기본적으로 Access에서 .NET 런타임을 호스팅하고 있습니다.

제한 사항은 링크 된 페이지에 4.0을 사용할 수 있다고하지만 실제로는 .NET 2.0 또는 3.5 런타임 만 호스팅 할 수 있다는 것입니다. 내가 아는 한, VBA에서 .NET 4.0+ 런타임을 호스팅하는 쉬운 방법은 없습니다. 4.0+ DLL을 호출하려고하면 "어셈블리가 런타임보다 최신"이라는 효과가 발생합니다.

예, 2.0 및/또는 3.5 런타임이 설치된 시스템에서도 사용해야합니다.

또한 네트워크 공유에서 직접 DLL을로드하지 않습니다. 이것은 (link)을 극복하는 것이 가능한 .NET 프레임 워크의 한계이지만 Access에서 DLL을 호스팅 할 때 수행 할 수 있는지 확실하지 않습니다.

"임베디드"DLL을 사용하려면 사용하기 전에 데이터베이스에서 내 보내야합니다. 좋은 장소는 사용자의 임시 폴더입니다.

EDIT : - 이전에 필자는 C# 클래스를 COM으로 노출 할 필요가 없다고했지만 필자는이 테스트를 거쳐 이것이 올바르지 않다는 것을 알았습니다.VBA에서 클래스를 올바르게 인스턴스화하려면 클래스에 [COMVisible(true)] 속성을 선언하거나 IDispatch 인터페이스를 구현해야합니다. 그렇지 않으면 CreateInstanceFrom은 Nothing을 반환합니다.

+0

액세스는 .net 4.5를 잘 사용해야합니다. 단순히 vb.net 클래스 개체를 만들고 COM interop에 대한 레지스터를 틱하면 클래스는 VBA 편집기 (도구 -> 참조)의 Windows "표준"목록에 나타납니다. .net 4.5를 사용하면 Access에서 제대로 작동합니다. 유일한 제안에 대해서는 x86 응용 프로그램 (실행 32 비트)으로 실행/컴파일하도록 .net 응용 프로그램을 제한 (강제)하는 것입니다. .dll의 내보내기가 필요할뿐만 아니라 .net을 표준 COM 객체로 등록하고 노출하는 regasm도 필요합니다. .net 전용 COM 개체로는 표준 창 .dll을 만들 수 없습니다. –

+0

@ AlbertD.Kallal 나는 당신이 약간 다른 것에 대해 이야기하고 있다고 생각합니다. COM 메소드를 사용하면 절대적으로 옳습니다. 상위 .NET 프레임 워크를 사용할 수 있습니다. 그러나 말했듯이 실제 SxS 등록을 사용할 수 없다면 등록이 필요합니다. 링크 된 답변 [여기] (http://stackoverflow.com/questions/1903220/side-by-side-com-interop-with-c-sharp-and-vba/13333819#13333819) 실제로 _hosts_ .NET Access의 프레임 워크는 조금 다르지만 reg가 필요하지 않습니다. 그 당시에 나는 그 대답을 썼다. 그러나 나는 SxS를 사용하고 있다고 생각하면서 약간의 개념을 혼란스럽게 생각했다. – transistor1

+0

실제로 내가 말할 수있는 한, 링크 된 대답은 단순히 등록하지 않고 .net COM 개체를 소비 할 수있게 해줍니다. 따라서 일반 ".net COM 객체를 사용할 수 있도록 허용하는 것과는 대조적으로"더 많거나 적게 "Access 내에서 응용 프로그램을 호스팅하는 것은 아닙니다. 그러나 확실히 .net 객체를 등록 할 필요가없는 "큰"보너스입니다. 따라서 종종 사용자는 .com 객체를 등록 할 수있는 권한이 없기 때문에 레지스트리를 변경해야합니다. 그래도 여전히 "훌륭한"점이 있으며,이 작업을 수행 할 수 있다면 .net 객체를 사용하는 Access 애플리케이션에이 기능을 채택 할 것입니다. –

관련 문제