2011-06-24 13 views
1

特定の列のセル値を行単位で取得し、SQLクエリを組み立ててcopypasteにするVBAマクロを作成しようとしています。基本的には、セルにテキストスニペットと変数を組み込みます。クエリには、入力としてカード番号と序数が必要なので、変数が必要です。Excel VBAのWhileループで問題が発生しました

マクロはほとんど準備が整いましたが、無限の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 

私はIsNull()の代わりにIsEmpty()を試しましたが、結果は同じです。私がここで紛失していることを教えてください。これは私がVBAで初めて試みたので、コードをよりエレガントにするためのアドバイスを私に与えることも自由です。あなたの努力のために事前にありがとうございます。

答えて

3

Stringであると、Cardnumberは決してNullまたはEmptyになりません。長さはゼロでなければなりません。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 
+0

私のために物事をクリアするためにどうもありがとうございました。 'Len(Cardnumber)> 0'を試してみましたが、唯一の問題はカードナンバーなしの行になる余分な時間を実行することです。これで私に手を差し伸べてもらえますか? – Andrew

+0

@Andrewこれはあなたのループで 'Cardnumber'に新しい値を代入する前に'> 0'の条件をチェックしているからです。条件を 'While'節から削除し、' While - Wend'を 'Do - Loop'に置き換え、' Cardnumber'に新しい値を代入した直後に条件をループ本体に入れます: 'Len(Cardnumber) = 0次にExit Do'とする。 – GSerg

+0

もう一度、ありがとう、コードは今すぐ使用する準備ができています。私はあなたの助けに非常に感謝しています。大切にしてください。 – Andrew

関連する問題