Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


2454 / 13645 ツリー ←次へ | 前へ→

【67866】配列について KIKI 11/1/14(金) 8:45 質問[未読]
【67867】Re:配列について neptune 11/1/14(金) 9:18 発言[未読]
【67883】Re:配列について KIKI 11/1/14(金) 17:23 お礼[未読]
【67868】Re:配列について Jaka 11/1/14(金) 9:23 発言[未読]
【67884】Re:配列について KIKI 11/1/14(金) 17:25 お礼[未読]
【67873】Re:配列について UO3 11/1/14(金) 11:06 発言[未読]
【67886】Re:配列について KIKI 11/1/14(金) 17:28 お礼[未読]
【67874】Re:配列について kanabun 11/1/14(金) 12:07 発言[未読]
【67888】Re:配列について KIKI 11/1/14(金) 17:40 お礼[未読]
【67880】Re:配列について momo 11/1/14(金) 16:42 発言[未読]
【67889】Re:配列について KIKI 11/1/14(金) 17:44 お礼[未読]
【67890】Re:配列について momo 11/1/14(金) 17:52 発言[未読]
【67935】Re:配列について KIKI 11/1/18(火) 9:56 お礼[未読]

【67866】配列について
質問  KIKI  - 11/1/14(金) 8:45 -

引用なし
パスワード
   配列を二つ使用しているマクロがあります

Dim As 配列1(10)
Dim As 配列2(10)

そこで、条件によって、配列1(10)を使用したり、配列2(10)を使用したりしてます

今、悩んでいるのが、
配列1(10)に何も値が格納されていなかったら、
配列2(10)の値を指定セルに代入

配列1(10)に値が格納されているなら、
配列1(10)の値を指定セルに代入

とさせたいのですが、
配列の有無はどのように記述すればいいのでしょうか?

IsObjectになるのでしょうか?

'現在は下記のように記述してあるのですが、
IsObjectっていうのは、
値が無いときにTrueを返すんでしょうか?
いまいち、逆の発想のような気がして、ピンときません

'配列1(10)に値が無い場合は、
If IsObject(配列1(10)=True then
  For i = 0 to ubound(配列2)
   Cells(i+1,"A").Value=配列2(i)
  Next i
'配列1(10)に値が有る場合は、
Else
  For i = 0 to ubound(配列1)
   Cells(i+1,"A").Value=配列1(i)
  Next i
End If

上記のような書き方が正しいのでしょうか?
 

【67867】Re:配列について
発言  neptune  - 11/1/14(金) 9:18 -

引用なし
パスワード
   ▼KIKI さん:
案のみですが、

Dim As 配列1()
Dim As 配列2()
と宣言しておいて
・必要な時のみ必要な要素数だけredimで再定義し、
・確認はuboundでエラーが出るか否かを確認
・必要がなくなった時にeraseする

よく用いる手法かと思います。

【67868】Re:配列について
発言  Jaka  - 11/1/14(金) 9:23 -

引用なし
パスワード
   配列は、変数の型によって初期値がすでに入っているので、その辺も考慮しなければなりませんね。

Sub aaa()
Dim 配列1(10) As Long
N = Application.CountA(配列1)
MsgBox N
End Sub

Sub bbb()
Dim 配列1(10) As String
N = Application.CountA(配列1)
MsgBox N
End Sub

Sub ccc()
Dim 配列1(10) As Variant
N = Application.CountA(配列1)
MsgBox N
End Sub

Sub aaa2()
Dim 配列1(10) As Long
配列1(10) = 0 '0を入れる。
N = Application.CountA(配列1)
MsgBox N
End Sub

【67873】Re:配列について
発言  UO3  - 11/1/14(金) 11:06 -

引用なし
パスワード
   ▼KIKI さん:

こんにちは

個人的な好みとしては、neputuneさんのアドバイスのように、配列が有効かどうかで
判断する方式がよろしいのではと思います。(動的配列の宣言と、配列の動的な生成)

ところで、配列1(10) と LBoundを略しておられるのが、ちょっと気になります。
KIKIさんもご認識されているとおり、この場合のLBoundは 0 となります。
従って要素としては 配列(0) から 配列(10) までの 「11個」ですね。
ですから、セルの行も i+1 として 実際には A1 から A11 までの11セルを相手に
しておられるわけです。

でも、これってわかりにくくありませんか?
まず、セルをA1からA11まで11個処理するのに 配列1(11)ではなく配列1(10)と書かなきゃいけない。
逆に、よく、うっかりするのは A1からA10まで処理すべきなのに配列1(10)と書いてしまって
結果的に処理したくないA11までの処理となってしまうケースも。

宣言時(動的宣言のRedimも含め)は、配列1(1 to 11) と明示的に記述することをお勧めします。
そうしますと、セット時 i+1 なんてやらず i だけでよく、ここもわかりやすくなります。

【67874】Re:配列について
発言  kanabun  - 11/1/14(金) 12:07 -

引用なし
パスワード
   ▼KIKI さん:


>Dim As 配列1(10)
>Dim As 配列2(10)
失礼します。

まず、
> Dim As 配列1(10)
> Dim As 配列2(10)
こんな書き方ないですよね?

Dim 配列1(10)
Dim 配列2(10)

のまちがいでしょうかね?

で、そうだとして、上の配列宣言は「静的配列」と言われ、
宣言した時点で配列のサイズと初期化が行われています。
たとえば、
Dim a(10) As Long
と宣言すれば、要素が 0 から 10 までの 11 の要素を持つ
整数型の配列が、宣言され、なおかつ 個々の要素には 値0
がセットされています。

ですから、今回のご質問は、
配列変数の初期化がされているか、いないか、ということでは
ないような気がします。
「静的配列」として宣言する限り、すでに要素数も初期化も
されているわけですから。

> 今、悩んでいるのが、
> 配列1(10)に何も値が格納されていなかったら、
> 配列2(10)の値を指定セルに代入

という質問は、Jakaさんのレスにあるように、要素にすでに値が代入
されているか否かをどうやって調べたらいいのか?
あるいは、個々の要素に値が代入されているかを判定する方法
ということではないですか?

まぁ、後者なら、指定要素の値が宣言時にセットされた「初期値」
でなければ、という判定をするしかないような気がしますが。

【67880】Re:配列について
発言  momo  - 11/1/14(金) 16:42 -

引用なし
パスワード
   ▼KIKI さん:

そもそも Dimで宣言しているという事は
最初から値は入っていないわけですから、そのコード内で値を入れてる訳ですよね?
だとしたら、どこに値を入れたのかは値を入れる時にわかるのでは?

【67883】Re:配列について
お礼  KIKI  - 11/1/14(金) 17:23 -

引用なし
パスワード
   ▼neptune さん:

eraseステートメントについて、調べてみました
初期値に戻すことができるのですね?

早速使って試してみたいと思います

アドバイスありがとうございました


>▼KIKI さん:
>案のみですが、
>
>Dim As 配列1()
>Dim As 配列2()
>と宣言しておいて
>・必要な時のみ必要な要素数だけredimで再定義し、
>・確認はuboundでエラーが出るか否かを確認
>・必要がなくなった時にeraseする
>
>よく用いる手法かと思います。

【67884】Re:配列について
お礼  KIKI  - 11/1/14(金) 17:25 -

引用なし
パスワード
   ▼Jaka さん:

アドバイスありがとうございます
↓静的配列には、始めから初期値が存在しているということを
 今回初めて知りました
 勉強になりました
 
>配列は、変数の型によって初期値がすでに入っているので、その辺も考慮しなければなりませんね。
>

早速、作成しなおしてみます

ありがとうございました

【67886】Re:配列について
お礼  KIKI  - 11/1/14(金) 17:28 -

引用なし
パスワード
   ▼UO3 さん:

なるほどですね
↓教えていただいたように書き直してみます
 たしかに、いつも悩んでしまって、分からなくなることも多々でした
 下記のように書けばいいんですね
 ありがとうございました
 とっても、助かります 

>
>宣言時(動的宣言のRedimも含め)は、配列1(1 to 11) と明示的に記述することをお勧めします。
>そうしますと、セット時 i+1 なんてやらず i だけでよく、ここもわかりやすくなります。

【67888】Re:配列について
お礼  KIKI  - 11/1/14(金) 17:40 -

引用なし
パスワード
   ▼kanabun さん:
>▼KIKI さん:
>
>
>まず、
>> Dim As 配列1(10)
>> Dim As 配列2(10)
>こんな書き方ないですよね?

おっしゃるとおりです
凡ミスです
すみません・・
>

配列の要素について、いろいろ調べてみました
結果、
kanabunさんが、
言われるように、指定要素が初期値に値するかどうか?の判定でやってみたいと思いました
早速、書き直してみます

とても助かりました
ありがとうございます

【67889】Re:配列について
お礼  KIKI  - 11/1/14(金) 17:44 -

引用なし
パスワード
   ▼momo さん:

複数の配列をモジュール内で、
配列を格納し、

配列が初期値かどうか?の条件によって、
処理を変えているので、
どうしても、今回のような質問になってしまいました

もう少し、勉強します

返信ありがとうございました

【67890】Re:配列について
発言  momo  - 11/1/14(金) 17:52 -

引用なし
パスワード
   ▼KIKI さん:
えっと、配列に入れるコードがぜったいありますよね?
で、配列1と2のどちらかに入れるための振り分けがあるんだと思います。

なので、たとえばフラグを設けて

Sub test()

Dim 配列1(1 To 11) As Long
Dim 配列2(1 To 11) As Long
Dim IntFlg As Integer

If 配列1に値を入れる場合 Then
 IntFlg = 1
 For i = 1 To 11
  配列1(i).Value = i
 Next i
ElseIf 配列2に値を入れる場合 Then
 IntFlg = 2
 For i = 1 To 11
  配列2(i).Value = i
 Next i
End If

If IntFlg = 1 Then
  For i = 1 To 11
   Cells(i, "A").Value = 配列1(i)
  Next i
ElseIf IntFlg = 2 Then
  For i = 1 To 11
   Cells(i, "A").Value = 配列2(i)
  Next i
End If
End Sub

のようにする事でも出来るのかな?
と思ったのです。

【67935】Re:配列について
お礼  KIKI  - 11/1/18(火) 9:56 -

引用なし
パスワード
   ▼momo さん:

フラグをたてるという方法もあるんですね
アドバイスありがとうございます
こちらも、ちょっと試してやってみます

助かります

ありがとうございました

2454 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free