如何在VBA事件驱动的编程中的工作表SelectionChange过程中创建动态范围?

时间:2019-07-04 13:23:49

标签: excel vba

我必须在excel中设计一个试卷模板,每个问题都有四种不同类型的答案,如

"Yes/No", 
"Ture/False", 
"Multiple Choice/Single Answer",
"Multiple Choice/Multiple Answer".

如果用户选择"Yes/No"并尝试回答更多然后两个回答,则会弹出一条错误消息。 如果用户选择“ Multiple Choice/Multiple Answer"并且仅选择一个答案并移至另一个单元格或列,则会弹出错误消息。 ...等等其他类型的问题。

为此,我使用了事件驱动的编程,请使用工作表SelectionChange过程。我的代码运行正常,但不是动态的,它只对一个问题起作用,而我的模板中有100个问题。

此模板中使用了四列 Column A, B, C and D分别的名称"Sr.No."问题编号。被提及,“ Question”问题在此列,"Answer Type"的答案类型在下拉列表中被提及。“正确选项”用户需要从此处选择“真”作为正确的选项

我的代码在这里:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

' section 1

' for Multiple Choice/Multiple answer
' if user select less than 2 answer
rw = 9
rng1 = rw + 1
rng2 = rw + 4

If Worksheets("Question paper").Range("C" & rw).Value = "Mutilple Choice/ Mutiple Answer" And _
    WorksheetFunction.CountIf(Range("D" & rng1 & ":" & "D" & rng2), "TRUE") < 2 Then
    MsgBox "Select at least 2 ""TRUE"" option"

' for Multiple Choice/Single Answer
' if user select more than 1 answer
ElseIf Worksheets("Question paper").Range("C" & rw).Value = "Mutilple Choice/Single Answer" And _
    WorksheetFunction.CountIf(Range("D" & rng1 & ":" & "D" & rng2), "TRUE") > 1 Then
    MsgBox "Select only 1 ""TRUE"" option"

    ' if user doesn't select any answer
    ElseIf Worksheets("Question paper").Range("C" & rw).Value = "Mutilple Choice/Single Answer" And _
        WorksheetFunction.CountIf(Range("D" & rng1 & ":" & "D" & rng2), "TRUE") < 1 Then
        MsgBox "Select only 1 ""TRUE"" option"

' for Yes/No Answer
' if user select more than 1 answer
ElseIf Worksheets("Question paper").Range("C" & rw).Value = "Yes/No" And _
    WorksheetFunction.CountIf(Range("D" & rng1 & ":" & "D" & rng2), "TRUE") > 1 Then
    MsgBox "Select only 1 ""TRUE"" option"

        ' if user doesn't select any answer
        ElseIf Worksheets("Question paper").Range("C" & rw).Value = "Yes/No" And _
            WorksheetFunction.CountIf(Range("D" & rng1 & ":" & "D" & rng2), "TRUE") < 1 Then
            MsgBox "Select at least 1 ""TRUE"" option"

' for True/False Answer
' if user select more than 1 answer
ElseIf Worksheets("Question paper").Range("C" & rw).Value = "True/False" And _
    WorksheetFunction.CountIf(Range("D" & rng1 & ":" & "D" & rng2), "TRUE") > 1 Then
    MsgBox "Select only 1 ""TRUE"" option"

        ' if user doesn't select any answer
        ElseIf Worksheets("Question paper").Range("C" & rw).Value = "True/False" And _
            WorksheetFunction.CountIf(Range("D" & rng1 & ":" & "D" & rng2), "TRUE") < 1 Then
            MsgBox "Select at least 1 ""TRUE"" option"


' for Free Form(Essay) answer
ElseIf Worksheets("Question paper").Range("C" & rw).Value = "Free Form(Essay)" And _
    WorksheetFunction.CountIf(Range("D" & rng1 & ":" & "D" & rng2), "TRUE") > 0 Then
    MsgBox "Do not select any option,it is a free form question"

'ElseIf Worksheets("Question paper").Range("C" & rw).Value = "Free Form(Essay)" And _
'    Worksheets("Main Sheet").Range("C32") = "" Then
'    MsgBox "Please fill details in cell C32 in ""Main Sheet"" tab"

End If
End Sub

在我当前的代码中,它仅适用于一个问题,要针对另外99个问题实施该代码,我必须复制相同的代码99次,并为问题行号分配一个变量。

我希望有100个或更多问题的动态代码。

2 个答案:

答案 0 :(得分:1)

对其进行了测试,可以发现当前行是否使用Target.row值

rw = Target.row

因为您只使用固定值9而不是当前目标行进行检查

答案 1 :(得分:0)

首先,我将此公式放在另一列= IF(AND(B10 <>“”“,C10 <>”“),” Q“,0)这个公式给我一个问题编号,即用户正在使用的问题。 用户在“ B”列中需要输入一个问题,在“ C”列中有一个问题类型的下拉列表,例如“是/否”,“正确/错误” ... 在“ D”列中,我在用户正在工作的问题的开头得到“ Q”。在“ D”列的末尾,我放了= sum公式,所以我得到了问题编号。

在另外2列中,我制作了一个表格,其中针对每个问题都提到了行号,例如: 问号行号 1 10 2 15 3 25

现在只需使用vlookup公式即可获得用户正在工作的问题的行号。

现在,我只需在VBA代码中的变量中分配此单元格值,如下所示: 私人子Worksheet_SelectionChange(按目标值作为范围)

rw = Range("XFB762").Value
rng1 = rw + 1
rng2 = rw + 4

If Worksheets("Question paper").Range("D" & rw).Value = "Multiple Choice/ Multiple Answer" And _
    WorksheetFunction.CountIf(Range("E" & rng1 & ":" & "E" & rng2), "TRUE") < 2 Then
    MsgBox "Select at least 2 ""TRUE"" option"

现在范围是动态的。而且效果很好。