5

定義行に「Set」キーワードを入れていた問題を解決しましたが、知りたいのは「なぜ」ですか?

基本的に、私はこれを行っています:

Dim startCell, iCell as Range
For Each iCell in Range(whatever)
    If iCell.value <>"" Then
        Set startCell = Cells(iCell.Row + 1, iCell.Column)
    End If
Next iCell

「Set」キーワードを省略しても、コードは正常にコンパイルされますが、ローカル変数ウィンドウで、そのタイプが「Variant / Object/Range」ではなく「String」に変更されていることがわかります。なぜそれが起こるのでしょうか?

4

3 に答える 3

14

これが理由です。あなたがこれを言うとき:

Dim startCell, iCell As Range

あなたはこれをしたと思います:

Dim startCell As Range, iCell As Range

しかし、あなたが実際に行ったことはこれです:

Dim startCell 'As Variant, by default
Dim iCell As Range

これは典型的なVBAの間違いです。DimほとんどのVBAプログラマーはそれを実現しました。そのため、ほとんどのVBAプログラマーは、ステートメントごとに1つの変数(つまり、1行に1つ)のみを宣言することに頼っています。そうでなければ、その間違いを犯すのは簡単すぎて、後でそれを見つけるのは難しいです。

したがってDim startCell、変数をVariant型(と同等Dim startCell As Variant)として暗黙的に宣言しました。

あなたがこれを言うとき:

Set startCell = Cells(iCell.Row + 1, iCell.Column)

Variantは、参照割り当ての右側にあるもののタイプ(範囲)を取得します。しかし、あなたがこれを言うとき:

startCell = Cells(iCell.Row + 1, iCell.Column)

キーワードがないSetと、参照を割り当てるのではなく、変数に値を割り当てます。変数startCellは、右側の値のタイプを取得します。そのタイプは何ですか?RangeオブジェクトのデフォルトのプロパティはValueです。したがって、のタイプを取得しますCells(iCell.Row + 1, iCell.Column).Value。そのセルに文字列が含まれている場合は、文字列を取得します。

于 2012-06-18T19:28:10.433 に答える
3

Setオブジェクトへの参照を割り当てるLet(または単純な割り当て) ために使用され、オブジェクト (存在する場合) の値を割り当てます。

  Dim a As Variant
  Set a = ActiveSheet.Cells(1)
  'TypeName(a) = Range, a now contains reference to the cell's range
  a = ActiveSheet.Cells(1)
  'TypeName(a) = Double or String, whatever is in the Cell, a contains the cell's value
于 2012-06-18T18:51:43.457 に答える
1

オブジェクトを変数に割り当てるとき は、 Setキーワードを使用する必要があります。Cells(iCell.Row + 1, iCell.Column)Rangeオブジェクトを返すため、Setを使用する必要があります。そうしないと、誰もが好む VBA エラーが発生します91: Object variable or With block variable not set

編集:

Range オブジェクトには、'Value' プロパティであるデフォルトの戻りプロパティもあります。Range("A1") を参照するだけの場合、バリアントのデフォルトとしてその範囲 'Value' が使用されます。これが、データ型が事前にわかっている場合にバリアントを使用しないようにする理由です。

于 2012-06-18T18:50:03.003 に答える