Excel VBA中的While循环问题

时间:2011-06-24 10:15:02

标签: excel vba loops while-loop

我正在尝试编写一个VBA宏,它逐行获取给定列中的单元格值,并为我组装一个SQL查询来进行copypaste。它基本上将文本片段和变量放在一个单元格中。查询需要cardnumbers和序数作为输入,因此需要变量。

宏已经准备就绪,但它会陷入无限的While循环中。

Sub Query()

Dim Row As Integer
Row = 8

Dim Cardnumber As String
Cardnumber = Range("D" & Row)

Dim Number As Integer
Number = 1

Range("E30").Select
ActiveCell.Value = "SELECT cardnumber, first_name || ' ' || last_name FROM ( SELECT cardnumber, first_name, last_name, c.OrderNo FROM ag_cardholder ch, (SELECT '%" & Cardnumber & "%' cardmask, " & Number & " OrderNo from dual "

While IsNull(Cardnumber) = False

    Row = Row + 1
    Number = Number + 1
    Cardnumber = Range("D" & Row)

    ActiveCell.Value = ActiveCell.Value & "UNION ALL SELECT '%" & Cardnumber & "%', " & Number & " OrderNo from dual "

Wend

ActiveCell.Value = ActiveCell.Value & ") c WHERE ch.cardnumber LIKE c.cardmask ORDER BY c.OrderNo ) t"

End Sub

我尝试过IsEmpty()而不是IsNull(),结果是一样的。请让我知道我在这里缺少什么。另外,请随意给我任何建议,使代码更优雅,因为这是我在VBA的第一次尝试。提前感谢您的努力。

1 个答案:

答案 0 :(得分:3)

成为StringCardnumber永远不会是NullEmpty。它只能有零长度Len(Cardnumber) = 0

如果CardnumberVariant,您可以使用IsEmpty来测试单元格值是否为空。
没有必要使用IsNull,因为Excel中的单元格值永远不会Null。即使从数据库中提取Null,Excel也会将其替换为Empty


回答你的下一个问题:我会将该代码重构为:

Sub Query()

  Dim InnerSelect As String
  Dim CurCell As Range: Set CurCell = ActiveSheet.Range("D8")
  Dim Number As Long: Number = 1

  Do
    Dim Cardnumber As String
    Cardnumber = CurCell.Value

    If Len(Cardnumber) = 0 Then Exit Do

    If Len(InnerSelect) = 0 Then
      InnerSelect = "SELECT '%" & Cardnumber & "%' cardmask, " & Number & " OrderNo from dual "
    Else
      InnerSelect = InnerSelect & "UNION ALL SELECT '%" & Cardnumber & "%', " & Number & " OrderNo from dual "
    End If

    Number = Number + 1
    Set CurCell = CurCell.Offset(1, 0)
  Loop

  Range("E30").Value = _
    "SELECT cardnumber, first_name || ' ' || last_name FROM ( SELECT cardnumber, first_name, last_name, c.OrderNo FROM ag_cardholder ch, (" & _
    InnerSelect & _
    ") c WHERE ch.cardnumber LIKE c.cardmask ORDER BY c.OrderNo ) t"

End Sub