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.EN
和Resources.FR
。
每个工作表都包含一个ListObject
/“表”,并且可以(应该)隐藏。 这些列基本上都是Key
和Value
,所以你的数据看起来像这样在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
,所以如果用户使用不受支持的语言,则仍然显示一些内容。