Excel VBA質問箱 IV

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

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


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

【78267】飛び飛びのセルに一次元配列を配列で代入する方法 himuro 16/6/15(水) 14:13 質問[未読]
【78269】Re:飛び飛びのセルに一次元配列を配列で代... β 16/6/15(水) 16:01 発言[未読]
【78270】Re:飛び飛びのセルに一次元配列を配列で代... β 16/6/15(水) 16:05 発言[未読]
【78271】Re:飛び飛びのセルに一次元配列を配列で代... himuro 16/6/15(水) 16:27 質問[未読]
【78274】Re:飛び飛びのセルに一次元配列を配列で代... β 16/6/15(水) 17:08 発言[未読]
【78281】Re:飛び飛びのセルに一次元配列を配列で代... himuro 16/6/16(木) 3:05 お礼[未読]
【78275】Re:飛び飛びのセルに一次元配列を配列で代... β 16/6/15(水) 17:17 発言[未読]
【78277】Re:飛び飛びのセルに一次元配列を配列で代... 亀マスター 16/6/15(水) 19:13 発言[未読]
【78282】Re:飛び飛びのセルに一次元配列を配列で代... himuro 16/6/16(木) 3:20 お礼[未読]

【78267】飛び飛びのセルに一次元配列を配列で代入...
質問  himuro  - 16/6/15(水) 14:13 -

引用なし
パスワード
   一次元配列の値を、飛び飛びのセル範囲に配列を使って代入する方法を教えて下さい。

飛び飛びのセル範囲は、alphaという名前付きセルで、A1:A5, C1:C5, E1:E5を参照している事にします。

一次元配列の値が"a, b, c, d, e, f, g..."だとすると、
A1からA5にはa~eが、C1~C5にはf~j, E1~E5にはk~oが入る感じです。

for eachで飛び飛びのセル範囲を一つずつ走査して代入する事はできましたが、やはり速度が気になるので配列を使って処理したいです。

2次元配列を作り、その配列に最初の一次元配列の値を格納して、
最後にalphaに代入する感じでしょうか。

しかし具体的なコードの書き方がいまいち分かりません。
よろしくお願いします。

【78269】Re:飛び飛びのセルに一次元配列を配列で...
発言  β  - 16/6/15(水) 16:01 -

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

確かにセル範囲への値書き込みは セル毎に行うより、まとめて、どさっと書きこんだほうが
圧倒的に効率はよくなります。
(例に挙げられたのは サンプル というか考え方でしょうけど、これぐらいのセル数なら
 ほとんど変わりはありませんが)

ただし、とびとびの複数セル領域への一括書きこみは不可能です。
あくまで、1領域ごとの書き込みになります。

次に、具体的には、どこの値をそれぞれのセル範囲に転記したいのでしょうか。
それを(1つの例としてでもいいので)提示願えませんか。
そのほうが、より具体的な回答につながると思いますので。

お先走って申し上げると、値を格納する配列は、今回の場合、全体としては1次元配列、
その中の要素が、各領域に書きこむべき2次元配列になると思います。

【78270】Re:飛び飛びのセルに一次元配列を配列で...
発言  β  - 16/6/15(水) 16:05 -

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

もう1つ申し上げておきます。
転記元がどうなっているのかにもよりますが、効率アップは、転記時の話です。

転記元セル領域 --> いったん配列に納めて --> 転記先セル領域に書き込み

これでは、かえって(微々たるものですが)処理時間が増えます。
こういう場合なら 転記元セル領域から転記先セル領域に書きこむべきですよ。

【78271】Re:飛び飛びのセルに一次元配列を配列で...
質問  himuro  - 16/6/15(水) 16:27 -

引用なし
パスワード
   ▼β さん:
>▼himuro さん:
>
>もう1つ申し上げておきます。
>転記元がどうなっているのかにもよりますが、効率アップは、転記時の話です。
>
>転記元セル領域 --> いったん配列に納めて --> 転記先セル領域に書き込み
>
>これでは、かえって(微々たるものですが)処理時間が増えます。
>こういう場合なら 転記元セル領域から転記先セル領域に書きこむべきですよ。

なるほど、具体的にはこのような感じになります。

'wordは可変。1つだったり20個だったりする。
dim word: word = "a, b, c, d, e, f, g, h, i, j, k, l, m, n, o"

dim arr1: arr1 = split(word, ",")

dim i, max: max = UBound(arr1)

dim a as range

'alphaはrange("A1:A10, C1:C10, E1:E10")の名前付きセル
for each a in alpha
a = arr1(i)
i = i + 1
if i > max then exit for
next a

このようなコードを、配列を使うことにより効率化できるでしょうか。

【78274】Re:飛び飛びのセルに一次元配列を配列で...
発言  β  - 16/6/15(水) 17:08 -

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

コメントしたように、本当の必要性が判然としません。
頭の中で考えたテーマのような気がします。

いずれにしても、コメントしたように、とびとびの複数領域に一括して転記することは不可能。
やるなら、1つずつです。

こちらも頭の中で考えます。
f という1次元配列(要素数は不明)に格納された値を alpha 内の各セルに
配列経由で書きこみます。

Sub Test()
  Dim f As Variant
  Dim t As Variant
  Dim r As Range
  Dim i As Long
  Dim j As Long
  Dim x As Long
  
  '以下はあくまでテストデータ
  ReDim f(1 To 50)
  For x = 1 To UBound(f)
    f(x) = "data" & x
  Next
  
  'ここから処理
  ReDim Preserve f(1 To Range("alpha").Count)
  x = 1
  For Each r In Range("alpha").Areas
    'あくまで、領域の中の1かたまりごとの処理
    ReDim t(1 To r.Rows.Count, 1 To r.Columns.Count)
    For i = 1 To UBound(t, 1)
      For j = 1 To UBound(t, 2)
        'それぞれの領域のそれぞれのセルに何をいれたいのかがわからないので
        '適当な値を埋め込み
        t(i, j) = f(x)
        x = x + 1
      Next
    Next
    
    r.Value = t 'alpsha内の1つの領域にまとめて書きこみ
  
  Next
  
End Sub

【78275】Re:飛び飛びのセルに一次元配列を配列で...
発言  β  - 16/6/15(水) 17:17 -

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

あるいは(ほとんど同じですが)

Sub Test2()
  Dim f As Variant
  Dim t As Variant
  Dim r As Range
  Dim i As Long
  Dim j As Long
  Dim x As Long
  Dim mx As Long
  
  '以下はあくまでテストデータ
  ReDim f(1 To 10)
  For x = 1 To UBound(f)
    f(x) = "data" & x
  Next
  
  'ここから処理
  x = 1
  mx = UBound(f)
  For Each r In Range("alpha").Areas
    'あくまで、領域の中の1かたまりごとの処理
    ReDim t(1 To r.Rows.Count, 1 To r.Columns.Count)
    For i = 1 To UBound(t, 1)
      For j = 1 To UBound(t, 2)
        'それぞれの領域のそれぞれのセルに何をいれたいのかがわからないので
        '適当な値を埋め込み
        If x <= mx Then
          t(i, j) = f(x)
        Else
          t(i, j) = Empty
        End If
        x = x + 1
      Next
    Next
    
    r.Value = t 'alpsha内の1つの領域にまとめて書きこみ
  
  Next
  
End Sub

【78277】Re:飛び飛びのセルに一次元配列を配列で...
発言  亀マスター  - 16/6/15(水) 19:13 -

引用なし
パスワード
   横から失礼します。

配列とは関係のない話なのですが、処理速度の向上を目指すなら、数式の再計算と画面更新を停止するだけでも効果があると思います。
提示された条件のセル数はそう多くないので影響は小さいかもしれませんが、実務で使うものがもっとセル数が多かったり、計算式を多用しているのであれば、それなりに有効かと思います。

'再計算停止
Application.Calculation = xlCalculationManual
'画面更新停止
Application.ScreenUpdating = False

'実際の処理

'再計算開始
Application.Calculation = xlCalculationAutomatic
'画面更新開始
Application.ScreenUpdating = True

【78281】Re:飛び飛びのセルに一次元配列を配列で...
お礼  himuro  - 16/6/16(木) 3:05 -

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

仕事から帰ってきて返信が遅くなりました。

二つ提示して頂いたソースをじっくりデバッグしながら動かしてみました。
.areasプロパティを使ったことが無かったのと、配列の使い方がよく分かっていなかったので、このようなソースは思い浮かびませんでした。

一度にではないとはいえ、セル範囲毎に一気に書き込めるなら、もっと数が増えれば実に効率的な処理だと思いました。
とても勉強になります。

>コメントしたように、本当の必要性が判然としません。
>頭の中で考えたテーマのような気がします。

私が提示したソースは実際に書いて動かしてみたものと、処理方法は全く同じで、結果も意図した状態を再現できています。データ自体を簡単にしただけであって、回答者さんを混乱させる意図は全くなかった事は釈明しておきたいと思います。

その上で言葉を付け足すとすると、私がした事は、テキストボックスに入力した記号区切りのコード(実際はアルファベット一文字ではなく、英数字の文字列)を、表形式で一列おきに記号文字を取り除いてただそのまま転記した事です。転記したコードの横に文字を入力させるスペースを残しています。テキストボックスの元の値は、他にもそれを元に色んな用途で加工を施します。

今回、私の力では提示したソースのように、転記先の範囲セルをループして、一つ一つのセルを踏みながら代入する方法しか書けませんでした。
もっと精進したいと思います。

今回は迅速に回答して下さりどうも有難う御座いました。

【78282】Re:飛び飛びのセルに一次元配列を配列で...
お礼  himuro  - 16/6/16(木) 3:20 -

引用なし
パスワード
   ▼亀マスター さん:
>横から失礼します。
>
>配列とは関係のない話なのですが、処理速度の向上を目指すなら、数式の再計算と画面更新を停止するだけでも効果があると思います。

返信有難うございます。
再計算ですが、ブックによっては常に手動の状態で運用しています。自動だと、関数で処理する時だけでなく、手動でセルの値を変更した時にも必ず重くなるのが痛いと感じます。worksheet_changeの先頭に手動再計算入れても、何も変わらないですよね。あれはつまり、再計算された後に呼ばれるイベントだと解釈しました。

なので、私は画面更新停止とイベントの停止をよく関数の頭に書く事が多いです。

worksheet_changeの中でif文をたくさん作り、個別に必要なcalculateを呼んでいます。

知らないことだらけなので、また是非アドバイスを下されば幸いです。

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