#vba #ms-access
#vba #ms-access
Вопрос:
У меня есть модуль, который можно вызвать из любой части моего приложения, чтобы проверить, установлен ли определенный шрифт в системе пользователя, а если нет — установите шрифт и проверьте еще раз, прежде чем продолжить
Основное приложение
if RequiredFont.Run(strFontName) = FALSE Then '(error message and exit sub)
Модуль «RequiredFont»
Public Function Run(Font As String) As Boolean
if check(Font) = FALSE Then
Run = FALSE
Install(Font)
if check(Font) = TRUE Then Run = TRUE
Else
Run = TRUE
End If
Private Function Check(Font as String) as Boolean
'code to check the font exists on the users localmachine, returns true/false
End Sub
Private Sub Install(Font as String)
'code to install the font on the users localmachine,
End Sub
Мой первый вопрос:
Это лучший способ сделать аргументы доступными для всех функций и вспомогательных модулей, чтобы передавать их при каждом вызове? (как показано выше) …. или есть простой способ объявить аргумент как переменную для всего модуля при вызове Run()?
Мой второй вопрос:
Есть ли способ избежать выполнения () все вместе и просто напрямую вызвать имя модуля «RequiredFont», я помню, что на других языках вызов sub по определенному имени автоматически запускает этот sub при вызове модуля
Спасибо
РЕДАКТИРОВАТЬ — так теперь выглядит мой код:
Private FontName As String
Private FontFile As String
Public Function Run(strFontName As String, strFontFile As String) As Boolean
FontName = strFontName
FontFile = strFontFile
Run = False
If CheckFont() = False Then InstallFont
If CheckFont() = True Then
Run = True
Else
'message error"
End If
End Function
Private Function CheckFont() As Boolean
'code to check if the font is installed
On Error Resume Next
'Create a temporary StdFont object
With New StdFont
' Assign the proposed font name
.Name = FontName
' Return true if font assignment succeded
If (StrComp(FontName, .Name, vbTextCompare) = 0) = False Then
CheckFont = False
Else
CheckFont = True
End If
End With
End Function
Private Sub InstallFont()
' code to install the font
MsgBox "You need the following font installed to continue." _
amp; vbNewLine _
amp; vbNewLine amp; "'" amp; FontName amp; "'" _
amp; vbNewLine _
amp; vbNewLine amp; "Click OK to launch the font. Please click the INSTALL button at the top"
OpenFile (PATH_TO_FONTS amp; FontFile)
End Sub
Комментарии:
1. Я хочу предложить вам выполнить эту проверку (и установить шрифт, если необходимо) только один раз, когда ваше приложение открыто. Сделать функцию постоянно доступной может быть отличной идеей, но это слишком сложно для того, что вы хотите сделать здесь.
2. Приложение будет использоваться для открытия шаблонов Word и заполнения их данными из базы данных…. но каждый шаблон word имеет разные шрифты, и иногда некоторые люди не будут использовать эту часть приложения, поэтому проверка при каждой загрузке программы будет ненужной, если они никогда не используют эту функцию
Ответ №1:
Использование аргументов функции — хорошая практика кодирования, таким образом, вы точно знаете, что входит и что выходит из функции.
Однако вы можете использовать глобальную переменную, которая будет установлена один раз при Run
вызове и по-прежнему будет доступна для других функций.
'could also be Private to hide it from other modules
Public myFont As String
Public Function Run(Font As String) As Boolean
myFont = Font
'...
End Sub
Private Function Check() as Boolean
' you can access myFont here
End Sub
Private Sub Install()
'idem
End Sub
Что касается вашего второго вопроса, я не думаю, что вы можете.
Комментарии:
1. будет ли это код, который лучше подходит для модуля класса?
2. @IanJackson Если вы хотите проверить несколько шрифтов, то да, безусловно, но только для одного это кажется неэффективным.
Ответ №2:
Вы можете объявлять необязательные функции и устанавливать значения по умолчанию:
Public Function fxMyFunction _
(Optional lngProj As Variant, _
Optional strFruit As Variant = "banana", _
Optional booTest As Boolean = False) As String
'' IsMissing requires that lngProj be a Variant
booNoProject = IsMissing(lngProj)
fxMyFunction = strFruit
End Function
Optional
Аргументы должны следовать за необязательными аргументами.
О функциях, которые «запускаются при включении»
Вам нужно вызывать функции и вспомогательные модули по имени. Для стандартного модуля VBA нет функции «автономного запуска». VBA «включает» все модули при компиляции.
Модули класса VBA — это то, где вы найдете эквивалент конструкторов. Инвестирование в версию объектной ориентации VBA не кажется полезным для ваших текущих потребностей. Если вы пойдете в этом направлении, некоторые аспекты начнут казаться вам знакомыми (хотя, возможно, достаточно, чтобы разочароваться, поскольку OO остается функцией, которая была добавлена позже и выглядит со стороны).
Ответ №3:
Как указано в @z, вы можете использовать глобальную переменную, хотя это плохая практика.
Что касается вопроса 2, вы можете присвоить своей функции уникальное имя и не называть свой модуль для его запуска, например
findOrInstallFont(Fontname)
Комментарии:
1. Не знаю, почему я этого не учел…. Я просто назову основную функцию «RequiredFont ()» так же, как и модуль, и поскольку я не буду ссылаться на определенную часть этого модуля — она никогда не должна быть rwuiredfont.requiredfont()
2. Однако в целом хорошей практикой является явный вызов функций по модулю. Это обеспечивает ясность позже. Я живу этим. Поэтому, хотя я могу представить, как назвать функцию «main» после ее модуля, я бы все равно назвал ее as
RequiredFont.RequiredFont()
. На практике это выглядело бы такvbRequiredFont.RequiredFont()
, потому что для меня короткий префикс для указания типа объекта — еще одна незаменимая практика. Опять же, специфично для Access.