是否可以在VBA中修复或声明单元格的类型?

时间:2012-03-16 00:23:08

标签: excel vba types excel-vba

我知道在VBA中,我们可以做到

Cells(4, 2).Value = 100      'the cell is an integer
Cells(4, 2).Value = True     'the cell is Boolean
Cells(4, 2).Value = "abc"    'the cell is Text

是否可以修复或声明单元格的类型,例如,让Cells(4,2)仅接受布尔值,以便将IntegerText分配给Cells(4, 2)给出错误?

3 个答案:

答案 0 :(得分:5)

[编辑此解决方案可以从VBA实现,但不能在VBA中使用,即无法阻止VBA用户将单元格值设置为任何内容(尽管不能在Excel工作表中手动设置) 。不确定OP究竟想要什么。]

使用数据验证。

你可以通过VBA来做到这一点:

Range("A1").Validation.Add Type:=xlValidateList, Formula1:="TRUE,FALSE"

或手动:(在Excel 2003中:数据>验证...)

enter image description here

现在,您只能在单元格A1中输入布尔TRUEFALSE。如果您尝试输入其他内容,例如一个数字:

enter image description here

使用数据验证,您还可以限制单元格仅接受数字,仅限整数,一定长度的文本,基本上只接受任何内容。例如,要仅接受文本和数字,您可以使用Allow:Custom,Formula:=NOT(ISNUMBER(A1))

答案 1 :(得分:4)

如果您确实想要指定单元格类型,则不能。据我所知,VBA中的所有单元格都包含变体数据类型。

如果您的意思是变体的数据类型,那么您可以这样或那样做。这是一个建议,它有点快速和肮脏,但它的工作原理。您需要将它放在工作表代码模块中。请注意,它不会测试你的bool范围,int范围,不论是什么交叉,如果它们会导致你出现问题。

Private Sub Worksheet_Change(ByVal Target As Range)

    On Error GoTo handler

    Dim cell As Range, _
        boolRng As Range, _
        intRng As Range

    Set boolRng = Union(Sheet1.Range("A1:B2"), Sheet1.Range("E:E"))
    Set intRng = Union(Sheet1.Range("B7:K12"), Sheet1.Range("M:M"))

    If Not Intersect(Target, boolRng) Is Nothing Then
        For Each cell In Intersect(Target, boolRng)
            If cell.Value <> "" Then
                cell.Value = CBool(cell.Value)
            End If
        Next cell
    End If

    If Not Intersect(Target, intRng) Is Nothing Then
        For Each cell In Intersect(Target, intRng)
            If cell.Value <> "" Then
                cell.Value = CInt(cell.Value)
            End If
        Next cell
    End If

    Exit Sub

handler:
    Select Case Err.Number
        Case 13 'Type mismatch, raised when cint/cbool/c*** fails
            cell.Value = ""
            Resume Next
        Case Else
            Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
    End Select

End Sub

编辑:我注意到如果错误地分配了值,则要引发错误,您可以在错误处理部分中执行此操作。而不是

Cell.value = ""
Resume Next

您可以使用

Err.Raise ISuggestAnEnumForErrorNumbers, "Sheet1.Worksheet_Change(Event)", "Attempted to assign wrong type to cell."

答案 2 :(得分:4)

我是JFC关于使用数据验证的第二个建议。

要测试它,请将此代码放在一个模块中(经过测试和测试

Sub Sample()
    With Sheets("Sheet1").Range("A1")
        .Validation.Delete
        .Validation.Add Type:=xlValidateList, Formula1:="TRUE,FALSE"
        .Value = "SID"
    End With
End Sub

并在相关表格中

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo Whoa

    If Not Intersect(Target, Range("A1")) Is Nothing Then
        Application.EnableEvents = False

        On Error Resume Next
        If Not Target.SpecialCells(xlCellTypeSameValidation).Cells.Count < 1 Then
            Dim currentValidation As Excel.Validation
            Set currentValidation = Target.Validation

            If currentValidation.Type = xlValidateList Then
                '~~> I am using INSTR. If you want you can split it using "," as delim 
                '~~> and check for the value.
                If Not InStr(1, currentValidation.Formula1, Target.Value, vbTextCompare) Then
                    MsgBox "Incorrect Value"
                    Target.ClearContents
                End If
            End If
        End If
        On Error GoTo 0
    End If
LetsContinue:
    Application.EnableEvents = True
    Exit Sub
Whoa:
    MsgBox Err.Description
    Resume LetsContinue
End Sub

现在尝试在模块中运行Sub Sample()