У вас есть End Sub
, но нет Sub
заявления ... это весь код? Что, если пользователь отменяет запросы?
Предполагая, что вы находитесь в стандартном модуле (например, Module1.bas
), вы захотите, чтобы он имел Option Explicit
вверху, а затем оператор Sub
определяет процедуру, которую нужно реализовать - подумайте и о том, чтобы сделать ее явно Public
:
Option Explicit
Public Sub WherePutMe()
'TODO
End Sub
Сказанное «Куда меня положили» - ужасное название для процедуры. Рекомендуется использовать значимые имена, которые передают цель кода - и поскольку процедуры делают что-то , вам нужно, чтобы их имена обычно начинались с глагола.
Unqualified, InputBox
вызывает VBA.Interaction.InputBox
, стандартную библиотечную функцию VBA, которая запрашивает у пользователя строку, и пользователь может отменить из этого приглашения. Когда это происходит, вы получаете нулевой строковый указатель, который неявно преобразуется в пустую строку - но тогда пользователь вполне может ввести пустую строку и нажать Ok , поэтому прежде чем мы проверяем ввод, мы сначала нужно знать, как запрос был отклонен.
Это быстро усложняется и хаотично c. Мы могли бы абстрагировать эту сложность за функцией:
Private Function TryGetUserInput(ByVal prompt As String, ByRef result As String) As Boolean
result = InputBox(prompt)
TryGetUserInput = (StrPtr(result) <> 0)
End Function
И теперь мы можем сделать это:
Option Explicit
Public Sub WherePutMe()
Dim userRowInput As String, userRow As Long, isValid As Boolean
Do While Not isValid
If TryGetUserInput("Enter a row number", userRowInput) Then
'user submitted a value, now validate it
If IsNumeric(userRowInput) Then
'looks legit
userRow = CLng(userRowInput)
'...but is it?
isValid = userRow > 0
End If
Else
'user cancelled the prompt
Exit Sub
End If
If Not isValid Then MsgBox "Invalid row number. Please enter a positive integer between 1 and 1,048,576.", vbExclamation
Loop
'TODO: get and validate the column letter
End Sub
Избегайте кода, который делает слишком много предположений (нарушенное предположение => ошибка; подумайте о как любая конкретная инструкция может потерпеть неудачу и выдать ошибку, которая отправляет все в пламя), и не стесняйтесь разбить вещи на небольшие специализированные процедуры и функции - как вышеупомянутый l oop будет выглядеть довольно аккуратно в своем собственном TryGetValidRowNumber
функция, которая возвращает False
в случае отмены пользователем, True
в противном случае с выходным параметром ByRef
, содержащим целочисленное значение Long
, которое вызывающий абонент может использовать напрямую:
Public Sub WherePutMe()
Dim rowNumber As Long
If Not TryGetValidRowNumber(rowNumber) Then Exit Sub
Dim columnLetter As String
If Not TryGetValidColumnLetter(columnLetter) Then Exit Sub
Dim targetCell As Range
Set targetCell = ActiveSheet.Range(columnLetter & rowNumber)
'TODO consume the targetCell as needed
End Sub