VBA Excel - 将字符串变量作为一行代码运行

时间:2017-11-23 15:51:23

标签: excel vba excel-vba language-translation

为了允许来自不同国家/地区的用户使用我的应用程序,我想在每个现有用户表单(标签,命令按钮,msgbox,框架等等)的初始化时初始化每个对象的翻译。应用

我会在Languages表单中写下所有翻译:

screenshot

我已经制作了第一个用户表单,用户输入他的登录名,密码并选择他的语言。

在此步骤之后,主用户窗体称为"菜单"将推出。

我已经尝试在我要运行的msgbox中输入一段代码(如下所示)来查找代码行(例如:menu.commandbutton1.caption="Envoyer email"

Private Sub UserForm_Initialize()

    ' Definition of language selected during login
    Set langue = Sheets("Languages").Cells.Find("chosen", 
    lookat:=xlWhole).Offset(-1, 0)

     ' Initialisation of the texts in the selected language
     Dim cel As Range
     Dim action As String
     For Each cel In Sheets("Languages").Range("d3:d999")
         If cel <> "" Then
             action = cel & "=" & """" & cel.Offset(0, -2) & """"
             MsgBox (action)
         End If
     Next cel

 End Sub

我已经阅读过有关此主题的一些主题,但这些主题并不完全符合我想要做的事情。

如果您有解决方案或解决方法,那将非常有用。

2 个答案:

答案 0 :(得分:2)

如果你只是想要不同的MsgBox,基于coutry,这可能是实现它的最简单方法。想象一下你的文件是这样的:

enter image description here

然后,这样简单的事情可以让你根据国家/地区使用不同的字符串:

Public Sub TestMe()

    Dim country             As String
    Dim language            As Long

    country = "Bulgaria" 'or write "England" to see the difference
    language = WorksheetFunction.Match(country, Range("A1:B1"), 0)

    MsgBox (Cells(2, language))
    MsgBox "The capital of " & country & " is " & (Cells(3, language))

End Sub

整个技巧的想法只是传递正确的列,这是通过WorksheetFunction.Match完成的。

答案 1 :(得分:1)

从我有here的旧CR帖子中获取,此解决方案几乎可以模仿.NET .resx资源文件,您可以轻松地查看如何将其扩展到其他语言,如果我今天要编写它我可能会使用Index + Match查找而不是那个效率相当低的循环 - 但无论如何它都可以很好地运行:

  

资源标准模块

Option Explicit
Public Enum Culture
    EN_US = 1033
    EN_UK = 2057
    EN_CA = 4105
    FR_FR = 1036
    FR_CA = 3084
End Enum

Private resourceSheet As Worksheet

Public Sub Initialize()

    Dim languageCode As String

    Select Case Application.LanguageSettings.LanguageID(msoLanguageIDUI)

        Case Culture.EN_CA, Culture.EN_UK, Culture.EN_US:
            languageCode = "EN"

        Case Culture.FR_CA, Culture.FR_FR:
            languageCode = "FR"

        Case Else:
            languageCode = "EN"

    End Select

    Set resourceSheet = Worksheets("Resources." & languageCode)

End Sub

Public Function GetResourceString(ByVal resourceName As String) As String

    Dim resxTable As ListObject
    If resourceSheet Is Nothing Then Initialize
    Set resxTable = resourceSheet.ListObjects(1)

    Dim i As Long
    For i = 1 To resxTable.ListRows.Count
        Dim lookup As String
        lookup = resxTable.Range(i + 1, 1)
        If lookup = resourceName Then
            GetResourceString = resxTable.Range(i + 1, 2)
            Exit Function
        End If
    Next

End Function

与.NET .resx文件类似,这个想法是每种语言都有一个工作表,例如: Resources.ENResources.FR

每张工作表都包含一个ListObject /“表格”,可以(应该)隐藏。这些列基本上是KeyValue,因此您的数据在工作表Resources.EN上看起来像这样:

Key                                Value
menu.caption                       Menu
menu.commandbutton1.caption        Send email
menu.commandbutton1.controltiptext Click to send the document

Resources.FR工作表会有一个类似的表,具有相同的键和特定于语言的值。

我热烈建议使用更具描述性的名字;例如而不是menu.commandbutton1.caption,我称之为SendMailButtonText,而不是menu.commandbutton1.controltiptext,我称之为SendMailButtonTooltip。如果您的按钮实际上名为CommandButton1,请继续并将其命名为SendMailButton - 稍后再感谢。

您的代码可以像这样“本地化”您的用户界面:

SendMailButton.Caption = GetResourceString("SendMailButtonText")

Resources.Initialize程序负责根据Application.LanguageSettings.LanguageID(msoLanguageIDUI)了解要使用的资源表 - 并回退到EN,因此如果用户的语言不受支持,则表示您还在展示一些东西。