Я начинаю модифицировать Excel VBA, чтобы локализовать его на разных языках. Я собираюсь присвоить переменную caption.value и присвоить значение переменной в соответствии с желаемым языком.
И в моем примере, когда язык установлен заранее, я хотел бы присвоить каждой переменной (имя в первом столбце) ее значение.
Вопрос в том, нужно ли мне сначала установить переменную (public ln_Date как строку), а после поиска ее значения в первом столбце и присвоить ее значение (переменная = диапазон (имя_переменной + смещение (язык), 1). Текст) Или есть возможность создавать на лету при поиске в диапазоне переменную с ее типом (публичная строка) и ее значением?
Я пытаюсь для каждой определенной ранее переменной выполнить поиск в диапазоне и присвоить ей значение, но по мере развития программы функция становится все более и более большой/сложной, и мне кажется, что это не лучший способ делайте что-то, поскольку мне нужно добавлять циклы для каждой новой языковой переменной.. В конце концов, это похоже на лабиринт
Идея состоит в том, что, поскольку мне нужно использовать этот текст на правильном языке в нескольких позициях в файле Excel и в различных формах, я хочу иметь возможность назначать текст в соответствии с языком переменной и после вызова этой переменной в мой UserForm_Initialize, например: UserForm.Caption = Ln_Title, и с помощью этого в одной позиции я определяю значение заголовка формы, и каждый раз, когда я открываю форму, назначается правильный язык (ну, возможно, это не лучшее решение, но я думаю, что это меньше кода потребляет)
Невозможно получить доступ к имени переменной во время выполнения, поэтому ваш код будет выглядеть следующим образом (я думаю, вы хотите установить именованные диапазоны для всех переменных?)
Dim Ln_Date As String
Ln_Date = range("Ln_Date" + offset(language), 1).Text
(... and so on for every variable)
Вместо этого вы можете подумать об использовании коллекции или словаря.
Я предлагаю не считывать переведенные слова в переменные, а создать небольшую функцию, которая выдает нужный текст всякий раз, когда это необходимо. Самый простой вариант может выглядеть так (я предполагаю, что таблица перевода находится на отдельном листе под названием Translations
— измените его по своему усмотрению).
Function getLanguageColumn(language As String) As Long
With ThisWorkbook.Sheets("Translations")
Dim col As Long
On Error Resume Next
col = Application.Match(language, ThisWorkbook.Sheets("Translations").Rows(1), 0)
On Error GoTo 0
If col = 0 Then col = 2 ' Default: First column
End With
getLanguageColumn = col
End Function
Function getTranslation(code As String, language As String)
Dim col As Long
col = getLanguageColumn(language)
Dim translation As String
With ThisWorkbook.Sheets("Translations")
On Error Resume Next
translation = WorksheetFunction.VLookup(code, .UsedRange, col, False)
On Error GoTo 0
If translation = "" Then translation = "Can't translate code " & code
End With
getTranslation = translation
End Function
Есть возможности для улучшения (улучшенная обработка ошибок, кэширование таблицы перевода в массив или словарь), но пока таблица не становится слишком большой, она подойдет.
Затем в своем коде вы вызываете эту функцию всякий раз, когда вам нужен переведенный термин. Например, вы создаете Sub в пользовательской форме под названием SetLabels
и вызываете эту процедуру, когда форма отображается (UserForm_Activate()
) или когда пользователь меняет язык, если вы предоставляете ему возможность выбора.
Dim Language As String
Private Sub UserForm_Activate()
Language = "FR"
SetLabels
End If
Sub SetLabels
Me.LabelDate = getTranslation("LN_Date", Language)
Me.LabelCreatedBy = getTranslation("Ln_Created by", Language)
(...)
End Sub
Спасибо за подробное объяснение, Черная кошка подумала о том же решении со словарем, я никогда не использовал этот элемент. Я проверю, большое спасибо
Вы можете реализовать функцию getTranslation
со словарем, если хотите (или если функция работает слишком медленно). Это принцип проектирования в программировании, согласно которому вызывающий код (например, в вашей форме) не заботится о том, как работает функция. Словари действительно мощные, и я часто ими пользуюсь, так что если вам интересно, покопайтесь в них. Я рекомендую youtube.com/watch?v=PrGchDgF3m4, но вы можете найти множество ресурсов, объясняющих это.
Для обхода проблемы используется Scripting.Dictionary. Результатом является не реальная переменная, а элемент объекта словаря, где вы можете ссылаться на элемент с предопределенным именем из вашей таблицы.
Это таблица языков на Sheet1
Это Sub для определения словаря.
Sub ActLang()
lang = "IT" 'GetLanguage 'this is a sub or to get the actual language in lang
Set ws = Worksheets("sheet1") 'the sheet where the language table is set.
Set found = ws.Range("A1:F1").Find(lang)
Dim varcoll As Scripting.dictionary
Set varcoll = New Scripting.dictionary
For i = 2 To ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
varcoll.Add ws.Cells(i, 1).Value, ws.Cells(i, found.Column).Value
Next i
End Sub
После запуска этого Sub вы можете обратиться к «переменной» следующим образом:
varcoll.Item("Var4")
или varcoll("Var4")
Примечание: параметр Item чувствителен к регистру.
Зачем вам для этого нужны переменные?