web-dev-qa-db-ja.com

範囲をバリアントの配列に割り当てる際に問題があるのはなぜですか

非常に単純なコード行でいくつかの問題が発生しています。事実を詳しく説明し、他の誰かがこの動作を再現できるかどうかを確認します。誰でも複製できる場合は、なぜそれが起こっているのかを説明したいと思います。

だから私は非常にシンプルなコードの行から始めることができます。

_Dim arr() As Variant
arr = Range("A1:A10")
_

これは期待どおりに行われ、arrには_A1:A10_の値が割り当てられます

なぜ次のコード行が機能しないのですか?

_Dim arr() As Variant
arr = WorkSheets("Sheet1").Range("A1:A10")
_

ワークシートの値がなくても、同じ範囲がアレイに正常に割り当てられたにもかかわらず、ランタイムエラー '13'タイプの不一致が発生します。

だが

_Dim arr As Variant
arr = Worksheets("Sheet1").Range("A1:A10")
_

そして

_Dim arr() As Variant
arr = Application.Transpose(Application.Transpose(Worksheets("Sheet1").Range("A1:A10")))
_

働く

答える前に、もう少し事実を教えてください。

_Dim arr() As Variant
arr = Worksheets(1).Range("A1:A10")
_

動作しません

Sheetsの代わりにWorksheetsを使用しても、すべて同じエラーが発生します。

作業コードに従ってRange("A1:A10").Worksheet.Nameを使用することで、アクティブな参照シートと同じシートであることを確認し、実際に出力で_Sheet1_と表示しています。

他のブックは開いていないため、別のブックを参照することもできません。

この最後のコードは、完全に機能するため、混乱を招くだけです!

_Dim arr() As Variant
Dim SampleRange As Range

Set SampleRange = Worksheets("Sheet1").Range("A1:A10")
arr = SampleRange
_

したがって、同じシートで同じ方法で定義された同じ範囲を使用すると、レンジ変数に割り当てたときに機能します。そしてそれを使用してください!予想どおり、これは、シートの定義方法に関係なく、WorkSheets関数とSheets関数の両方で機能します(ワークシートのインデックスまたは名前を使用でき、すべて正常に機能します)

誰かに役立つ場合は、Windows XPマシンでExcel 2007を使用してこれをテストしています。他のマシンではまだテストしていませんが、Windows 7で2003および2010でテストする予定です。 8、まだチャンスがありません。

PDATE:これがアレイと同じ正確な問題であるかどうかは100%確かではありませんが、浅いビューからはされる:

_ Range("B1:B3") = Range("A1:A3") 
_

上記のコードは機能しません。たとえA1:A3が入力されていても、日付、数値、文字列、数式は何でも、B1:B3に空白を書き込みます。

だが

_Range("B1:B3").Value = Range("A1:A3").Value
_

そして

_Range("B1") = Range("A1")
_

does動作します!

また、作業は次のとおりです。

_Range("B1:B3") = Application.Transpose(Application.Transpose(Range("A1:A3")))
_
26
user2140261

いいえ、それはバグではありません。

ポイントは、ValueがRangeオブジェクトのデフォルトプロパティであるため、暗黙的に使用されないのはなぜですか?私がリンクした質問を見ましたか? (FROM [〜#〜] chat [〜#〜]

以前の回答を投稿した専門家は、すでに非常に詳細に説明しています。説明は最小限に抑えますので、まだ質問がある場合はお知らせください。

最初にオブジェクトを理解しましょう。混乱しないように、処理対象を明確に示すこの小さなテーブルを作成しました。

enter image description here

次の図に示すように、Watchを追加して、特定のオブジェクトのTypeを表示することもできます。

enter image description here

だからあなたが言うとき

arr = Range("A1:A10")

Excelは、デフォルトプロパティが.Value。ただし、Excelがマインドリーダーではないため、またはWorksheets("Sheet1").Range("A1:A10")Rangeとして使用するか、Variantとして使用するかを理解するのに十分な知性があるため、他のケースではわかりません。

オブジェクトをRangeとして明示的に指定すると、Excelは必要なものを認識します。たとえば、これは機能します。

Dim arr() As Variant
Dim Rng As Range  
Set Rng = Worksheets("Sheet1").Range("A1:A10")
arr = Rng
32
Siddharth Rout

コメントを明確にします。
少なくとも私の意見を明確にするために、私はそれを答えとして投稿することにコメントすることはできません。

Dim arr As Variant '~~> you declare arr as Variant as what Tim said

どういう意味ですか?
これは、arrが任意の形式(整数、文字列、配列、オブジェクト、その他すべてのVariable Typeなど)をとることができることを意味します

Dim arr() as Variant '~~> you declare arr() as array which may contain Varying `Data Type`

どういう意味ですか?
これは、arr()配列変数が異なるData型を格納できることを意味します。
ObjectsまたはCollection of Objectsを除外します。

さて、なぜ次のように機能します:

1. Dim arr() As Variant: arr = Range("A1:A10")
2. Dim arr() As Variant: arr = Sheet1.Range("A1:A10")
3. Dim arr() As Variant: arr = Sheets("Sheet1").Range("A1:A10").Value

これも機能します:

4. Dim arr() as Variant
   Dim rng as Range

   Set rng = Sheets("Sheet1").Range("A1:A10")
   arr = rng

Collections of Objectsを配列に割り当てようとしていないため、上記のように動作します。
代わりに、特定のエンティティまたは値を割り当てています。
Rangeはオブジェクトですが、Collection of Objectsではありません。
No.1の例は、Sheets Collection Objectにアクセスせずに直接です。
同じことが当てはまります
No.2は、SheetオブジェクトであるがSheet1ではないCollection of Sheet Objectsを使用するためです。
No.3は自明です。.Valuearr配列に割り当てます。
No.4は、rngが既にRangeによってSetオブジェクトであり、これもCollection of Objectsではないため機能します。

したがって、この:

Dim arr() As Variant

arr = Sheets("Sheet1").Range("A1:A10")

excelはSheets Collection of ObjectsからObjectを割り当てようとしてこれを読み取るため、エラーが発生するため、機能しません。
これが少し理にかなっていることを願っています。

3
L42

Somethingの配列はSomethingと同じではありません。このSomethingは他の何かの配列になる可能性があるため。何かを配列として定義する場合、それに割り当てるものは、数値、テキスト、範囲、チャートオブジェクトなどの配列である配列でなければなりません。

予期しない動作が行われる場合、ほとんどの場合、簡単に行えるのは組み込みのデータ型変換だと思います。この変換は、オブジェクトのプロパティではなく、直接のオブジェクトである必要があります。

たとえば、RowsとColsはLongタイプですが、Byte/Doubleタイプをスローできます:

Cells(1,1.5)Cells(1,2)の値を与えます

1.5をLongに変換する必要はありません。 Excelはすべてをバックグラウンドで実行します。

何かの配列を定義してそれを割り当てると、Excelはバックグラウンドでタイプマッチングを行い、可能であれば値を設定します。

イミディエイトウィンドウでこれらを確認します。

?typename(Range("A1:A10").Value)Variant()を提供します<-これがDim arr() As Variantで問題なく動作する理由です

?typename(Range("A1:A10"))Rangeを提供します。ただし、arr where Dim arr() As Variantに割り当てると、ExcelはそのRangeの値を使用してRangeを配列に変換します。

ただし、Excelは、オブジェクト用のメモリを作成しない限り、オブジェクトに直接アクセスできない場合、変換に失敗するようです。例えば:

_Dim arr() As Variant, oRng As Range
Set oRng = Range("A1:A10")
arr = oRng
Set oRng = Worksheets("Sheet1").Range("A1:A10")
arr = oRng
_

上記のコードはすべて問題ありませんが、配列をスローしない限り、arr = ThisWorkbook.Worksheets("Sheet1").Range("A1:A10")を一度に変換して割り当てることはできません(ThisWorkbook.Worksheets("Sheet1").Range("A1:A10").ValueVariant())。

2
PatricK