Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ms access 是否存在Access 2010 64位的“打开文件”对话框?_Ms Access_Vba_Openfiledialog_Ms Access 2010 - Fatal编程技术网

Ms access 是否存在Access 2010 64位的“打开文件”对话框?

Ms access 是否存在Access 2010 64位的“打开文件”对话框?,ms-access,vba,openfiledialog,ms-access-2010,Ms Access,Vba,Openfiledialog,Ms Access 2010,如何获取Access 2010 64位的“打开文件”对话框?通常我会使用公共对话框控件,但它是32位的,不能与Access 2010 64位一起使用。我从来没有为打开的文件对话框使用过控件,因为它只是API调用的包装器。 此外,控件可能存在分发和版本控制问题,因此我会尽力避免这些问题。首先,“CommonDialog类”在32位版本的Office上似乎都不起作用。它给出了相同的OleDb错误。正如一位评论者指出的,这不是您应该使用的控件。虽然您可能还可以使用另一个ActiveX控件,但无法保证它

如何获取Access 2010 64位的“打开文件”对话框?通常我会使用公共对话框控件,但它是32位的,不能与Access 2010 64位一起使用。

我从来没有为打开的文件对话框使用过控件,因为它只是API调用的包装器。 此外,控件可能存在分发和版本控制问题,因此我会尽力避免这些问题。

首先,“CommonDialog类”在32位版本的Office上似乎都不起作用。它给出了相同的OleDb错误。正如一位评论者指出的,这不是您应该使用的控件。虽然您可能还可以使用另一个ActiveX控件,但无法保证它在您要部署数据库的每台计算机上都可用。除了Office和其他程序,My dev box上还有Visual Studio 6、VS 2008和VS 2010,所有这些程序都提供了典型用户所不具备的ActiveX DLL。此外,这些库中的许多都是不可再发行的,或者造成了独特的安装障碍,这可能根本不值得费心

到目前为止,最简单、最通用的解决方案是从Windows API调用“打开”对话框。它位于comdlg32.dll中,可用于可能针对的每个版本的Windows,并且不依赖于comdlg32.ocx。它还提供了比使用ActiveX控件更好的性能,因为它不需要额外的模块加载到内存中

所需的代码也不是很复杂。您需要为函数提供一个声明,该声明将创建“打开”对话框。它只接受一个参数,即包含用于初始化对话框的信息的实例,以及接收用户选择的文件的路径。因此,您还需要提供此结构的声明。VBA中的代码如下所示:

Private Type OPENFILENAME
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    lpstrFilter As String
    lpstrCustomFilter As String
    nMaxCustFilter As Long
    nFilterIndex As Long
    lpstrFile As String
    nMaxFile As Long
    lpstrFileTitle As String
    nMaxFileTitle As Long
    lpstrInitialDir As String
    lpstrTitle As String
    flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    lpstrDefExt As String
    lCustData As Long
    lpfnHook As Long
    lpTemplateName As String
End Type

Private Declare Function GetOpenFileName Lib "comdlg32.dll" _
    Alias "GetOpenFileNameA" (ByRef lpofn As OPENFILENAME) As Long
还有几个常量可以作为标志传递,以自定义对话框的行为。为完整起见,以下是完整列表:

Private Const OFN_ALLOWMULTISELECT As Long = &H200
Private Const OFN_CREATEPROMPT As Long = &H2000
Private Const OFN_ENABLEHOOK As Long = &H20
Private Const OFN_ENABLETEMPLATE As Long = &H40
Private Const OFN_ENABLETEMPLATEHANDLE As Long = &H80
Private Const OFN_EXPLORER As Long = &H80000
Private Const OFN_EXTENSIONDIFFERENT As Long = &H400
Private Const OFN_FILEMUSTEXIST As Long = &H1000
Private Const OFN_HIDEREADONLY As Long = &H4
Private Const OFN_LONGNAMES As Long = &H200000
Private Const OFN_NOCHANGEDIR As Long = &H8
Private Const OFN_NODEREFERENCELINKS As Long = &H100000
Private Const OFN_NOLONGNAMES As Long = &H40000
Private Const OFN_NONETWORKBUTTON As Long = &H20000
Private Const OFN_NOREADONLYRETURN As Long = &H8000&
Private Const OFN_NOTESTFILECREATE As Long = &H10000
Private Const OFN_NOVALIDATE As Long = &H100
Private Const OFN_OVERWRITEPROMPT As Long = &H2
Private Const OFN_PATHMUSTEXIST As Long = &H800
Private Const OFN_READONLY As Long = &H1
Private Const OFN_SHAREAWARE As Long = &H4000
Private Const OFN_SHAREFALLTHROUGH As Long = 2
Private Const OFN_SHAREWARN As Long = 0
Private Const OFN_SHARENOWARN As Long = 1
Private Const OFN_SHOWHELP As Long = &H10
Private Const OFS_MAXPATHNAME As Long = 260
为了方便起见,我将整个混乱包装在一个辅助函数中,您可以从VBA中调用该函数。它接受您通常需要为“打开文件”对话框设置的属性作为参数,处理Windows API本身的调用,然后返回用户选择的文件的完整路径,或者如果用户单击“取消”按钮,返回空字符串(
vbNullString
)。您可以测试调用代码中的返回值,以确定要采取的操作过程

'This function shows the Windows Open File dialog with the specified
' parameters, and either returns the full path to the selected file,
' or an empty string if the user cancels.
Public Function OpenFile(ByVal Title As String, ByVal Filter As String, _
    ByVal FilterIndex As Integer, ByVal StartPath As String, _
    Optional OwnerForm As Form = Nothing) As String

    'Create and populate an OPENFILENAME structure
    'using the specified parameters
    Dim ofn As OPENFILENAME
    With ofn
        .lStructSize = Len(ofn)
        If OwnerForm Is Nothing Then
            .hwndOwner = 0
        Else
            .hwndOwner = OwnerForm.Hwnd
        End If
        .lpstrFilter = Filter
        .nFilterIndex = FilterIndex
        .lpstrFile = Space$(1024) & vbNullChar & vbNullChar
        .nMaxFile = Len(ofn.lpstrFile)
        .lpstrFileTitle = vbNullChar & Space$(512) & vbNullChar & vbNullChar
        .nMaxFileTitle = Len(.lpstrFileTitle)
        .lpstrInitialDir = StartPath & vbNullChar & vbNullChar
        .lpstrTitle = Title
        .flags = OFN_FILEMUSTEXIST
    End With

    'Call the Windows API function to show the dialog
    If GetOpenFileName(ofn) = 0 Then
        'The user pressed cancel, so return an empty string
        OpenFile = vbNullString
    Else
        'The user selected a file, so remove the null-terminators
        ' and return the full path
        OpenFile = Trim$(Left$(ofn.lpstrFile, Len(ofn.lpstrFile) - 2))
    End If
End Function
哇,结果太长了。您需要将许多声明复制并粘贴到模块中,但实际需要处理的接口非常简单。下面是一个示例,说明如何在代码中实际使用它来显示“打开文件”对话框并获取文件路径:

Public Sub DoWork()
    'Set the filter string (patterns) for the open file dialog
    Dim strFilter As String
    strFilter = "Text Files (*.txt)" & vbNullChar & "*.txt*" & vbNullChar & _
                "All Files (*.*)" & vbNullChar & "*.*" & vbNullChar & vbNullChar

    'Show the open file dialog with the custom title, the filters specified
    ' above, and starting in the root directory of the C: drive.
    Dim strFileToOpen As String
    strFileToOpen = OpenFile("Choose a file to open", strFilter, 0, "C:\")

    'See if the user selected a file
    If strFileToOpen = vbNullString Then
        MsgBox "The user pressed the Cancel button."
    Else
        MsgBox "The user chose to open the following file: " & _
               vbNewLine & strFileToOpen 
    End If
End Sub

编写和测试此解决方案的最长时间实际上是试图找到如何打开VBA编辑器并在Access中编写宏。对于使用“粘贴”和“保存”主菜单的人来说,功能区可能是一项伟大的发明,但这真是一件痛苦的事。我整天都在使用软件,但还是找不到东西。[/rant]

这家伙有一个工具,可以生成与打开文件64位兼容的代码。这是免费软件


这是唯一有效的方法。

我错过了64位访问细节。您不太可能运行它,但如果您运行了,下面有一篇文章供您参考,它解释了如何更改API调用以使其工作--您必须使用新的长指针数据类型:

如果您相应地修改API代码,它应该可以在64位访问上正常工作

但你真的应该问一下为什么要使用64位访问。微软并不建议任何人使用64位Office,除非他们有需要它的具体原因(例如需要使用它提供的额外内存,特别是对于复杂的Excel电子表格模型)。Access绝对不是从64位转换中获益匪浅的应用之一

关于该主题的详细讨论:


简而言之,大多数人不应该运行64位Office,这正是您遇到的原因——它会导致外部依赖于32位组件和API的遗留代码失败。

您可以使用内置文件对话框。自2003年以来一直在那里

Dim f    As FileDialog 
Set f = Application.FileDialog(msoFileDialogFilePicker) 
f.Show 
MsgBox "file choose was " & f.SelectedItems(1) 
如果您愿意,您可以延迟绑定:

以上需求:Microsoft Office 14.0对象库

如果删除对14.0对象库的引用,则 代码将在没有任何引用的情况下工作:

Dim f    As Object 
Set f = Application.FileDialog(3) 
f.AllowMultiSelect = True 
f.Show 

MsgBox "file choosen = " & f.SelectedItems.Count 

因此,从2003年起,上述功能可以在运行时或常规版中使用,也可以在access 2010的32位或64位版本中使用

我处理这个问题已经有很长一段时间了

你上面所说的一切都有效,但还有最后一点需要补充。。。在WITH OFN声明下,您需要更改

.lStructSize = Len(ofn)


然后一切正常。

我刚刚在64位版本的Excel 2013中努力解决这个问题

结合了

  • 在传递给
    GetOpenFileNameA
  • 获取
    OPENFILENAME
    结构的大小时,将
    Len
    函数替换为
    LenB
    函数(如Max Albanese所述)
  • …多亏了此处提供的指导,我们做到了这一点:

    我无法想象这会不起作用。我在64位应用程序中使用了很多次打开文件对话框。您不能在32位版本的Windows上运行64位版本的Office,因此您应该处理64位版本的Office
    .lStructSize = LenB(ofn)