[[20141209232213]] 『再質問』(ちぃさん) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『再質問』(ちぃさん)

いつもお世話になります。

申し訳ないですが、また同じ過去の回答いただいた内容についての質問となります。
宜しくお願いします。

[[20141206172135]] ←コチラでも質問したのですがまだ理解できていない部分がありまして教えて頂きたく質問にまいりました。

[[20140708195505]]  ←でご教授いただきましたコードで

    ReDim tbl(1 To r.Count)
    Dim i As Long
    i = 1
    For Each c In r
        tbl(i) = c.Value
        i = i + 1

この部分がわかりません。

まず1点目 ReDim tbl(1 To r.Count) の部分。
ReDim の所で配列名として宣言している tbl 。
その tbl 配列内容という言い方が正しいのかはわからないのですが変数として宣言されている r の中の個数をカウント?という解釈で間違ってないでしょうか?(汗)

次に2点目 i = 1 の部分。
これは何故 1 なのでしょう?

次に3点目 tbl(i) = c.Value の部分。
tbl(i) これは全くわかりません。

次に4点目 i = i + 1 の部分。
2点目と3点目が理解できていないのでわかるはずがないのですが i + 1 を i - 1 とか i + 2 に変更しデバッグで確認してみると 「実行時エラー9」がでます。
i = i + 1 の部分を 'i = i + 1 としスルーさせるとエラーはでないですが転記は r の中にある最後の1つだけの転記になります。

考えてみたのですが理解ができません。

解説をお願いできないでしょうか。

どうか宜しくお願い致します。

< 使用 Excel:Excel2010、使用 OS:Windows7 >


 EXCEL の質問というよりは、プログラムのデータ構造に関する理解の問題かと思います。
 このあたりを読んで、概念を理解してみてはどうでしょうか。

 Visual Basic 中学校 > 初級講座 >第27回 配列
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard27.htm

 EXCELでお仕事−配列変数の利用
http://www.asahi-net.or.jp/~ef2o-inue/vba_k/sub04_070_07.html

 Wiki-配列
http://ja.wikipedia.org/wiki/%E9%85%8D%E5%88%97
(Mook) 2014/12/10(水) 07:58

肝心の、以下の部分を省略して質問しているのは困りますね。

    Dim r As Range
    Set r = Range("B5,J1,H7,E14,B8")

こう宣言し代入しているのだから、r.Count は r の要素の個数(=5個)になります。
ReDim tbl(1 To r.Count) と配列数を宣言しているのだから、これは

tbl(1)
tbl(2)
tbl(3)
tbl(4)
tbl(5)

という変数を定義したことになります。

次に、変数iは、i = 1 から始めているので、i = i + 1 はつまり、1 2 3 4 5 というように変化しますよね?
tbl(i) は、tbl()という配列変数のi番目という意味なだけ。

tbl(1) = Range("B5").Value
tbl(2) = Range("J1").Value
tbl(3) = Range("H7").Value
tbl(4) = Range("E14").Value
tbl(5) = Range("B8").Value

というのをループして処理していることになります。
ここでiの加算をやめてしまうと、tbl(i) は、すべて1番目になっちゃいます。

tbl(1) = Range("B5").Value
tbl(1) = Range("J1").Value
tbl(1) = Range("H7").Value
tbl(1) = Range("E14").Value
tbl(1) = Range("B8").Value

こうなるので、tbl(1)をどんどん上書きしていくだけになり、最後には Range("B8").Value だけが残ってしまいますよ。
(???) 2014/12/10(水) 09:05


(Mook)さん、(???)さん 回答ありがとうございます。

毎回、低レベルな質問ですみません。

すごく理解できた気がします。

ありがとうございました。

(ちぃさん) 2014/12/10(水) 17:11


i = 5 から始めて、i = i - 1 に変える、というのを試してみると、更に配列が理解できるかもです。
(???) 2014/12/10(水) 17:27

(???)さん ありがとうございます。

>i = 5 から始めて、i = i - 1 に変える
試してみました。
マイナスは逆から拾っていくのですね。

さらにUnionメソッドを使って

    Set r = Union(Range("A2,C2,E2,G2"), _
    Range("P9,F11,H11,J11,L11,N11,P11,R11"), _
    Range("R9"))
    ReDim tbl(1 To r.Count)
    Dim i As Long
    i = 5
    For Each c In r
        tbl(i) = c.Value
        i = i - 1
    Next c
で試すと「実行エラー9」
さらに
    Set r = Union(Range("A2,C2,E2,G2"), _
    Range("P9,F11,H11,J11,L11,N11,P11,R11"), _
    Range("R9"))
    ReDim tbl(1 To r.Count)
    Dim i As Long
    i = 5
    For Each c In r
        tbl(i) = c.Value
        i = i + 1
    Next c
で試すとまたまた「実行エラー9」

    Set r = Union(Range("A2,C2,E2,G2"), _
    Range("P9,F11,H11,J11,L11,N11,P11,R11"), _
    Range("R9"))
    ReDim tbl(1 To r.Count)
    Dim i As Long
    i = 13
    For Each c In r
        tbl(i) = c.Value
        i = i - 1
    Next c

これだとRange("R9")から1つづつ拾ってくれる。

なほほど。
これは変数 r の中にある途中からは拾えないということ?でしょうか?
もしかして勘違いしてます?でしょうか?(汗)

(ちぃさん) 2014/12/10(水) 18:26


もちろん、途中からでも始められますよ。
Unionで連結して、r.Countは13になっていますね。tbl()も、13個。
問題は、i =5 から始めて、13回ループしている点です。つまり、i の変化は、
5 6 7 8 9 10 11 12 13 14 15 16 17 になります。

tbl(1)
tbl(2)
tbl(3)
tbl(4)
tbl(5) = Range("A2")
tbl(6) = Range("C2")
tbl(7) = Range("E2")
tbl(8) = Range("G2")
tbl(9) = Range("P9")
tbl(10) = Range("F11")
tbl(11) = Range("H11")
tbl(12) = Range("J11")
tbl(13) = Range("L11")

あれ、tbl(14)以降は宣言されていませんね? これがエラーの原因です。

うまく動かなかった場合、ロジックの途中でブレークポイントを設定して処理を中断させ、
そこからはF8キーで1行ずつ実行しつつ、変数の内容を確認し、原因を調べてください。

それと、For Each c In r という取り出し方だと、指定されたRange全てを調べる、という意味になります。
まぁ入れた順番で取り出せるのですが、順番は指示していません。

もし、tbl(1) = Range("P9") から始めたい、という事でしたら、4回読み捨てるか、または以下のようにコーディングすると良いでしょう。
(使わないものを宣言する必要は無いから、rにRange("A2,C2,E2,G2")を含めない、というのがベストと思いますが)

    Dim tbl
    Dim r As Range
    Dim i As Long
    Dim iMax As Long

    Set r = Union(Range("A2,C2,E2,G2"), _
        Range("P9,F11,H11,J11,L11,N11,P11,R11"), _
        Range("R9"))

    iMax = r.Count - 4
    ReDim tbl(1 To iMax)

    For i = 1 To iMax
        tbl(i) = r(i + 4).Value
    Next i
(???) 2014/12/11(木) 09:04

(???)さん 回答ありがとうございます。

ん。。。。。
チョット意味がわからなくなってきました。(汗)

現在

    '//転記元のブックに書く
    Dim r As Range
    Dim c
    Dim tbl
    Dim iMax As Long

    '
    '//転記元シートを開いた状態で行う処理
    Set r = Union(Range("A2,C2,E2,G2"), _
    Range("P9,F11,H11,J11,L11,N11,P11,R11"), _
    Range("R9"))
    ReDim tbl(1 To r.Count)
    Dim i As Long
    'i = 1
    'For Each c In r
        'tbl(i) = c.Value
        'i = i + 1
     iMax = r.Count - 4
    ReDim tbl(1 To iMax)

    For i = 1 To iMax
        tbl(i) = r(i + 4).Value

    Next i

このようにしてますが私、間違っていますか?

変数の内容を確認してるとなにか変なんですが(汗)

iMax = r.Count - 4
ここの部分で 
「オブジェクト変数またはWithブロックが設定されていません」
とでてます。

Next i
の所ではループ回数をカウントされてます。

転記内容は

   Set r = Union(Range("A2,C2,E2,G2"), _
        Range("P9,F11,H11,J11,L11,N11,P11,R11"), _
        Range("R9"))
で指示していない部分の A6,A8,A10 が 1セルおきに転記されます。

こちらのままでだと

    '//転記元のブックに書く
    Dim r As Range
    Dim c
    Dim tbl
    Dim iMax As Long

    '
    '//転記元シートを開いた状態で行う処理
    Set r = Union(Range("A2,C2,E2,G2"), _
    Range("P9,F11,H11,J11,L11,N11,P11,R11"), _
    Range("R9"))
    ReDim tbl(1 To r.Count)
    Dim i As Long
    i = 1
    For Each c In r
        tbl(i) = c.Value
        i = i + 1

    Next c

Next c のところで転記指示をしている A2 から順番に表示されてました。

何か足りていないのでしょうか?
もし良ければ教えていただけないでしょうか。
(ちぃさん) 2014/12/11(木) 12:40


ああっ、私のミスです。 tbl(i)の代入箇所を、以下に変えてください。

        tbl(i) = r.Areas(Int(i + 4)).Value
(???) 2014/12/11(木) 13:09

あれ、でも iMax = r.Count - 4 の箇所ではエラーにならないはずです。
また、A6,A8,A10 のように飛び飛びにはならないはずですが、For文の内側でも i = i + 1 とかやってませんか?
For文自身がiを+1ずつ回してくれるので、更に i = i + 1 としてしまうと、1つずつ飛んでしまいますよ。
(???) 2014/12/11(木) 13:14

(???)さん 回答ありがとうございます。

>あれ、でも iMax = r.Count - 4 の箇所ではエラーにならないはずです。
すみません。
紛らわしい書き方をして申し訳ありません。
エラーがでるというとではないです。
ブレークポイントを設定してF8キーで1行ずつ実行している時にポインターを iMax = r.Count - 4 の r.Count の所にもってきた時にでます。
これはエラーという事?ではないですよね?
F8キーで1行ずつ実行していって最終は転記されますし。(汗)
先程の「オブジェクト変数またはWithブロックが設定されていません」 には謝りがありました。
正しくは
r.Count =<オブジェクト変数またはWithブロックが設定されていません>
です。

 tbl(i) = r.Areas(Int(i + 4)).Value でも
r.Areas =<オブジェクト変数またはWithブロックが設定されていません>
とでます。
tbl(i) だけの部分でも
tbl(i) =<型が一致しません>
とでます。
ですが転記は元の位置は P9,F11,H11,J11,L11,N11,P11,R11,R9 が選択され正しく処理されています。
転記先も正常に転記されます。
なので =<オブジェクト変数またはWithブロックが設定されていません> の表示が何を示しているのかな?と思っております。
ですが、
tbl(i) = r.Areas(Int(i + 4)).Value の部分を tbl(i) = c.Value に変更し直すとやはり A6,A8,A10 が1セルおきに転記されます。

日時 A6の値 空白 A8の値 空白 A10の値
転記はこのような感じであります。

tbl(i) = r.Areas(Int(i + 4)).Value に変更して正しく転記されているので
>For文の内側でも i = i + 1 とかやってませんか?
特になにも書き加えていませんので i = i + 1 はないかと。(汗)
不思議です。

現在は正しく処理されていますコードは

    '//転記元のブックに書く
    Dim r As Range
    Dim c
    Dim tbl
    Dim iMax As Long

    '
    '//転記元シートを開いた状態で行う処理
    Set r = Union(Range("A2,C2,E2,G2"), _
    Range("P9,F11,H11,J11,L11,N11,P11,R11"), _
    Range("R9"))
    ReDim tbl(1 To r.Count)
    Dim i As Long
    'i = 1
    'For Each c In r 未使用
        'tbl(i) = c.Value 未使用
        'i = i + 1 未使用
     iMax = r.Count - 4
    ReDim tbl(1 To iMax)

    For i = 1 To iMax
        'tbl(i) = r(i + 4).Value 未使用
        tbl(i) = r.Areas(Int(i + 4)).Value

    Next i
このような感じでございます。

どこかおかしい部分はありますでしょうか?

すみません。
ブレークポイントの設定でチョット勘違いしている部分があるのでしょうか?
ブレークポイントを設定したいコードの行の部分で F9 を押して 赤の●をつけているのですが(汗)
ブレークポイントを設定しても処理が中断されてない気がするのですが。(汗)
ブレークポイントを設定した状態でF8をおし1つづづ処理をしどんどん下へ下がっていき赤の●の部分がきてもそのまま処理が続行されて転記、Bookを保存しBookを閉じるまでいってしまうのですが。
http://vba.officehp.com/category/5189117-1.html

コチラを見て試しているのですが
ブレークポイントを設定した行で、プログラムが中断というようなことがないです。
何故でしょう?
現在ブレークポイントは Next i の所につけてます。

(ちぃさん) 2014/12/11(木) 16:06


ブレークポイント設定後、F5キーで実行すると、一気にブレークポイント位置まで進んで止まります。
F8キーはブレークポイントとは関係なく、1ステップ進めるのです。●の位置は、普通に実行した場合に止まる箇所です。

ソースの修正も問題ないです。コメントアウトした行は、削除してしまったほうが良いでしょう。
c という変数はもう使っていないので、Dim宣言から消しましょう。
c を全くセットしていないので、tbl(i) = c.Value と書いては駄目です。
セットしていない c を参照しようとするから、「オブジェクト変数または…」のエラーになったのですね。
(???) 2014/12/11(木) 16:22


(???)さん 回答ありがとうございます。

ブレークポイント勘違いしてました。
多分理解できました。

Dim宣言も未使用の場合は消した方がよいのですね。
気をつけます。

未使用のコード部分はシングルクオートを付けているのですが不十分でしたか。(汗)
手抜きでした。

勉強になりました。

ありがとうございました。
(ちぃさん) 2014/12/11(木) 17:33


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.