你有End Sub,但没有Sub 声明..这是整个代码吗?如果用户取消提示怎么办?
假设您在一个标准模块中(例如Module1.bas),您会希望它的顶部有Option Explicit,然后Sub 语句定义您需要实现的过程 - 考虑制作它也明确Public:
Option Explicit
Public Sub WherePutMe()
'TODO
End Sub
这就是说“把我放在哪里”是一个可怕的程序名称。最佳做法是使用有意义的名称来传达代码的目的 - 由于过程做某事,您会希望它们的名称通常以动词开头。
不合格,InputBox 正在调用VBA.Interaction.InputBox,这是一个提示用户输入字符串的 VBA 标准库函数,用户可以在该提示之外Cancel。当这种情况发生时,你得到的是一个空字符串指针,它隐式转换为一个空字符串 - 但是,用户可以很好地输入一个空字符串并点击 Ok,所以在我们验证输入之前,我们首先需要知道提示是如何被解除的。
这很快就会变得复杂和混乱。我们可以将这种复杂性抽象为一个函数:
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
避免做出过多假设的代码(假设错误 => 错误;想想任何给定的指令可能会失败并引发错误,从而将所有内容都付之一炬),并且毫不犹豫地将事情分解成小块,专门的过程和函数——像上面的循环在它自己的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