VBA Excel – 将stringvariables作为一行代码运行

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

我将在我的Languages表中写下所有的翻译:

截图

我已经做了第一个用户表单,用户input他的login名,密码并select他的语言。

在这一步之后,将会启动名为“菜单”的主要用户表单。

我已经试过在一个msgbox中input一段代码(在这里下面)来查找代码行,例如: 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 

我已经阅读了关于这个主题的一些话题,但是这些话题并不完全符合我想要做的事情。

如果您有解决scheme或解决方法,这将是非常有帮助的。

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

在这里输入图像说明

那么这样容易的事情可以让你根据国家使用不同的string:

 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完成的。

我从这里得到一个旧的CRpost,这个解决scheme几乎模仿.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 。 如果你的button实际上被命名为CommandButton1 ,那就把它命名为SendMailButton – 稍后再感谢你。

你的代码可以像这样“本地化”你的UI:

 SendMailButton.Caption = GetResourceString("SendMailButtonText") 

Resources.Initialize过程负责根据Application.LanguageSettings.LanguageID(msoLanguageIDUI)知道要使用哪个资源表,然后回退到EN ,所以如果用户使用不受支持的语言,则仍然显示一些内容。