【问题标题】:Defining a Literal 2D String Array in VBA在 VBA 中定义文字二维字符串数组
【发布时间】:2018-06-26 09:41:01
【问题描述】:

我正在尝试构建一个实用函数,以通过标准 Windows 文件对话框提示用户输入任意文件。

我想将文件类型过滤器列表作为二维字符串数组传递,其中每个子数组的第一个元素是文件类型描述,第二个元素是文件类型过滤器。

下面是我的功能:

'' GetFile  -  Lee Mac
''
'' Prompts the user to select a file using a standard Windows file dialog
''
'' msg - [str] Dialog title
'' ini - [str] Initial filename/filepath
'' flt - [arr] Array of filetype filters
''
Function GetFile(Optional strMsg As String = "Select File", Optional strIni As String = vbNullString, Optional arrFlt) As String
    Dim dia As FileDialog
    Set dia = Application.FileDialog(msoFileDialogFilePicker)
    With dia
        .InitialFileName = strIni
        .AllowMultiSelect = False
        .Title = strMsg
        .Filters.Clear
        If IsMissing(arrFlt) Then
            .Filters.Add "All Files", "*.*"
        Else
            Dim i As Integer
            For i = 0 To UBound(arrFlt, 1)
                .Filters.Add arrFlt(i, 0), arrFlt(i, 1)
            Next i
        End If
        If .show Then
            GetFile = .selecteditems.Item(1)
        End If
    End With
End Function

这可行,但是,当向函数提供文件类型过滤器参数时,我发现自己必须做这样的事情:

Function test()
    Dim arr(1, 1) As String
    arr(0, 0) = "Excel Files"
    arr(0, 1) = "*.xls;*.xlsx"
    arr(1, 0) = "Text Files"
    arr(1, 1) = "*.txt"

    GetFile , , arr
End Function

我也尝试了以下方法,但收到“下标超出范围”:

Dim arr() As Variant
arr = Array(Array("Excel Files", "*.xls;*.xlsx"), Array("Text Files", "*.txt"))

有没有更好的方法来定义我缺少的文字二维字符串数组?

非常感谢您的建议和反馈。

【问题讨论】:

  • 已删除我仅适用于 Excel 的答案。道歉。
  • @SMeaden 没问题 - 感谢您的时间和贡献!

标签: arrays ms-access vba


【解决方案1】:

因为您评论说您可以编辑 getFile 函数,所以您应该考虑这种方法。使用 Array 可能是一个简单直接的想法,但如果您的应用程序足够复杂,那么您的 Array 初始化可能会变得笨拙。

下面的方法只是对类的介绍,也许是对设计模式的介绍。看看吧。

Public Function test()

    Dim fe As New FileExtensions 'initialise your file extension class

    'Add filters
    fe.AddFilter "All Files", "*.*" 'add here or in class defaults
    fe.AddFilter "Excel Files", "*.xls; *.xlsx"
    fe.AddFilter "Text Files", "*.txt"

    GetFile , , fe
End Function

Function GetFile(Optional strMsg As String = "Select File", Optional strIni As String = vbNullString, Optional arrFlt) As String
    Dim dia As Object
    Set dia = Application.FileDialog(3)
    With dia
        .InitialFileName = strIni
        .AllowMultiSelect = False
        .Title = strMsg
        .filters.Clear

        'Simply retrieve the filters from extension class
        If Not IsMissing(arrFlt) Then
            Dim i As Long
            For i = 0 To arrFlt.getCount - 1
                .filters.ADD arrFlt.getDescription(i), arrFlt.getFilter(i)
            Next i
        End If
        If .Show Then
            GetFile = .selecteditems.item(1)
        End If
    End With
End Function

还有一个 FileExtensions 类

Option Compare Database
Option Explicit

Private Type FileExtension
    tDescription As String
    tFilter As String
End Type
Private Holder() As FileExtension

Public Sub class_initialize()
    ReDim Holder(0) ' or if you want to add default filters
End Sub

Public Sub AddFilter(Description As String, Filter As String)

    ReDim Preserve Holder(UBound(Holder) + 1)
    Holder(UBound(Holder) - 1).tDescription = Description
    Holder(UBound(Holder) - 1).tFilter = Filter

End Sub

Public Function getCount() As Long
    getCount = UBound(Holder)
End Function

Public Function getDescription(index As Long) As String
    getDescription = Holder(index).tDescription
End Function

Public Function getFilter(index As Long) As String
    getFilter = Holder(index).tFilter
End Function

【讨论】:

  • 哇 - 谢谢你的例子!我以前没有使用过类,所以这是一个很好的介绍。
【解决方案2】:

你的最后一个方法会起作用:

Dim arr() As Variant
arr = Array(Array("Excel Files", "*.xls;*.xlsx"), Array("Text Files", "*.txt"))

您的错误一定是由其他原因引起的。

【讨论】:

  • 谢谢 - 这确实适用于定义一个数组,但是,不是二维字符串数组,而是一个数组数组......因此,我没有使用 arr(0,0) 访问元素,而是使用arr(0)(0)... 访问它们
  • 确实如此。但它应该符合目的。
  • 确实 - 我可以修改上面的 GetFile 函数以期望使用此结构的数组,但我认为可能有一种更“正确”的方式来定义文字二维字符串数组,如看起来这应该是一个相对简单的练习。
【解决方案3】:

使用另一个实用函数来制作数组然后你可以:

GetFile , , StrsTo2d("Excel Files", "*.xls;*.xlsx")
GetFile , , StrsTo2d("Excel Files", "*.xls;*.xlsx", "Text Files", "*.txt")
GetFile , , StrsTo2d("Excel Files", "*.xls;*.xlsx", "Text Files", "*.txt", "FooFile", "*.foo")

Function StrsTo2d(ParamArray args() As Variant) As String()
    Dim     i As Long
    Dim num As Long: num = (UBound(args) - 1) / 2
    ReDim   out(num, 1) As String

    For i = 0 To num
        out(i, 0) = args(i * 2)
        out(i, 1) = args(i * 2 + 1)
    Next

    StrsTo2d = out
End Function

【讨论】:

  • 谢谢亚历克斯,这比我目前的方法更干净,虽然当然仍然填充一个空数组而不是定义一个文字数组......也许这在 Access VBA 中是不可能的。
  • 遗憾的是 vba/s/6 不支持任何类型的任何类型的变量初始化。
猜你喜欢
  • 1970-01-01
  • 2021-06-12
  • 2016-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
  • 1970-01-01
  • 2019-09-14
相关资源
最近更新 更多