No.8ベストアンサー
- 回答日時:
(2/2連投)
以下、サンプル。
◆◆準備
空のシートを2つ用意して、
それぞれシート名を"詳細"、"集計"としてください。
下記サンプル「元の表」(正味4行)はそのままコピーして、
"詳細"シートのA1セルにテキストデータとして貼付けて、
[データの区切り位置]機能で展開して使います。
"集計"シートは空のままです。
"詳細"シートの「元の表」
と
"集計"シートの各「Step」を記録した
イメージ画像を添付します。見づらいようでしたら一旦PCに落としてから拡大してみてください。
元の表
シート : 詳細
' ' ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
科目 ・国 ・国 ・国 ・国 ・数 ・数 ・数 ・数 ・英 ・英 ・英 ・英 ・社 ・社 ・理 ・理 ・選1 ・選1 ・選2 ・選2 ・選3 ・選3
番号 1 2 3 4 1 2 3 4 1 2 3 4 3 4 1 2 1 3 2 3 1 4
名前 佐藤 高橋 鈴木 田中 佐藤 高橋 鈴木 田中 佐藤 高橋 鈴木 田中 鈴木 田中 佐藤 高橋 佐藤 鈴木 高橋 鈴木 佐藤 田中
点数 75 59 92 95 89 73 68 96 100 72 78 61 73 75 82 86 67 62 93 83 75 80
' ' ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
※同一科目名が連続する部分はセルの結合を適用する想定で書いています。
処理後の表(結果)
シート : 集計
' ' ーーーーーーーーーーーーーーーーーーーー
番号 名前 科目 点数 科目数
1 佐藤 ・国・数・英・理・選1・選3 488 6
2 高橋 ・国・数・英・理・選2 383 5
3 鈴木 ・国・数・英・社・選1・選2 456 6
4 田中 ・国・数・英・社・選3 407 5
' ' ーーーーーーーーーーーーーーーーーーーー
◆◆テスト用サンプル
敢えて詳細な解説は書きません。
コードを読む、ようにしてください。
' ' =========================
Sub Re8247882test()
Dim mtxS As Variant ' 二次元配列、インプット
Dim mtxP As Variant ' 二次元配列、アウトプット
Dim arrTmp As Variant ' 一次元配列、仮設
Dim sTmp As String ' 科目名
Dim tnP As Long ' 人数
Dim ubS2 As Long ' レコード件数(配列のXSize(横方向サイズ))
Dim nNum As Long ' IDを拾う
Dim i As Long
Dim j As Long
Sheets("集計").Select ' ★
Range("A1:E5").ClearContents ' ★
MsgBox "処理開始" ' ★
tnP = 4
mtxS = Sheets("詳細").Cells.CurrentRegion
ubS2 = UBound(mtxS, 2)
ReDim mtxP(0 To 4, 1 To 5)
' ' ★ Step 1
' ' 項目名を一旦一次元配列に。
arrTmp = Split(" 番号 名前 科目 点数 科目数")
' ' arrTmp(0) = Empty
' ' arrTmp(1) = 番号
' ' arrTmp(2) = 名前
' ' arrTmp(3) = 科目
' ' arrTmp(4) = 点数
' ' arrTmp(5) = 科目数
For j = 1 To 5
Debug.Print "arrTmp(" & j & ") = " & arrTmp(j)
mtxP(0, j) = arrTmp(j)
Next j
Range("A1:E5").Value = mtxP ' ★
MsgBox "★ Step 1" ' ★
Stop ' ★
' ' ★ Step 2
For i = 1 To 4
mtxP(i, 1) = i
Next i
Range("A1:E5").Value = mtxP ' ★
MsgBox "★ Step 2" ' ★
Stop ' ★
' ' ★ Step 3
For i = 1 To 4
mtxP(i, 2) = mtxS(3, i + 1)
Next i
Range("A1:E5").Value = mtxP ' ★
MsgBox "★ Step 3" ' ★
Stop ' ★
' ' ★ Step 4
For j = 2 To ubS2
If mtxS(1, j) <> "" Then sTmp = mtxS(1, j)
nNum = mtxS(2, j)
mtxP(nNum, 3) = mtxP(nNum, 3) & sTmp
Next j
Range("A1:E5").Value = mtxP ' ★
MsgBox "★ Step 4" ' ★
Stop ' ★
' ' ★ Step 5
For j = 2 To ubS2
If mtxS(1, j) <> "" Then sTmp = mtxS(1, j)
nNum = mtxS(2, j)
mtxP(nNum, 4) = mtxP(nNum, 4) + mtxS(4, j)
Next j
Range("A1:E5").Value = mtxP ' ★
MsgBox "★ Step 5" ' ★
Stop ' ★
' ' ★ Step 結果
For j = 2 To ubS2
If mtxS(1, j) <> "" Then sTmp = mtxS(1, j)
nNum = mtxS(2, j)
mtxP(nNum, 5) = mtxP(nNum, 5) + 1
Next j
Range("A1:E5").Value = mtxP
MsgBox "結果" ' ★
End Sub
' ' =========================
' ' (' ★の行は提示用。処理内容とは無縁。)
◆◆実践サンプル
基本的にテスト用に書いたものなのですが、
テスト用サンプルでは、わざと分けて書いているものを纏めたものです。
' ' =========================
Sub Re8247882()
Dim mtxS As Variant ' 二次元配列、インプット
Dim mtxP As Variant ' 二次元配列、アウトプット
Dim arrTmp As Variant ' 一次元配列、仮設
Dim sTmp As String ' 科目名
Dim tnP As Long ' 人数
Dim ubS2 As Long ' レコード件数(配列のXSize(横方向サイズ))
Dim nNum As Long ' IDを拾う
Dim i As Long
Dim j As Long
tnP = 4
mtxS = Sheets("詳細").Cells.CurrentRegion
ubS2 = UBound(mtxS, 2)
ReDim mtxP(0 To 4, 1 To 5)
' ' Step 1
arrTmp = Split(" 番号 名前 科目 点数 科目数")
For j = 1 To 5
Debug.Print "arrTmp(" & j & ") = " & arrTmp(j)
mtxP(0, j) = arrTmp(j)
Next j
' ' Step 2, 3
For i = 1 To 4
mtxP(i, 1) = i
mtxP(i, 2) = mtxS(3, i + 1)
Next i
' ' Step 4, 5, 結果
For j = 2 To ubS2
If mtxS(1, j) <> "" Then sTmp = mtxS(1, j)
nNum = mtxS(2, j)
mtxP(nNum, 3) = mtxP(nNum, 3) & sTmp
mtxP(nNum, 4) = mtxP(nNum, 4) + mtxS(4, j)
mtxP(nNum, 5) = mtxP(nNum, 5) + 1
Next j
Sheets("集計").Range("A1:E5").Value = mtxP
End Sub
' ' =========================
No.9
- 回答日時:
#7、8、cjです。
書き忘れがあったので補足します。
テスト用サンプルを実行する際は、
VBE(Visual Basic Editor)を表示し、
テスト用サンプルにカーソル(キャレット)を当てた状態で
F5キーで実行。
(以下繰り返し)
MsgBoxが表示されたら、シート内容を確認して、Enterキー([OK])
StopステートメントでVBEに表示が戻ったら、
ローカルウィンドウで配列変数の内容を確認して、F5キー(再実行)
(以下繰り返し)
という手順になります。
No.7
- 回答日時:
(1/2連投)
' ' Sample 1 ====================
Sub 二次元配列処理_基本ループ()
Dim i As Long
Dim j As Long
Sheets("Sheet1").Select
Cells.ClearContents
MsgBox "二次元配列処理_基本ループ/実行"
For i = 1 To 5
For j = 1 To 4
Cells(j, i) = Chr(i + j + 63)
Next j
Next i
End Sub
' ' Sample 2 ====================
Sub 二次元配列処理_配列変数()
Dim mtx(1 To 4, 1 To 5) As Variant
Dim i As Long
Dim j As Long
Sheets("Sheet1").Select
Cells.ClearContents
MsgBox "二次元配列処理_配列変数/実行"
For i = 1 To 5
For j = 1 To 4
mtx(j, i) = Chr(i + j + 63)
Next j
Next i
Range("A1:E4").Value = mtx
End Sub
' ' Sample 3 ====================
Sub 二次元配列処理_コレクション()
Dim rng As Range
Dim i As Long
Dim j As Long
Sheets("Sheet1").Select
Cells.ClearContents
MsgBox "二次元配列処理_コレクション/実行"
Set rng = Range("A1:E4")
For i = 1 To 5
For j = 1 To 4
rng(j, i).Value = Chr(i + j + 63)
Next j
Next i
End Sub
' ' =========================
' ' (以上、新規ブックのSheet1を対象にテストしてください)
以上のサンプル3点は何れも
二次元配列を扱うサンプルで、
何れも同じ結果を返すものです。
このサンプル3点の違いを理解し使い分けたり使いこなしたり
出来ることは、二次元配列を扱う上で基本的なことです。
このうち、Sample 2 Sub 二次元配列処理_配列変数()
については、「配列変数を用いて二次元配列を処理」するものですが、
”2次元配列を使った具体的なサンプルソース”と仰るのは、
こういうことなのかな??と思いました。
でも、知りたいのはサンプルソースというより、
配列変数を使う場合の特長とか、どんな場合に利点を発揮できるかとか、
配列変数の周辺の事情とか条件とか、そういった処への関心、
という話なんじゃないでしょうか。
具体例を付した配列変数と二次元配列の扱いについてのサンプル
を次の投稿で、あげてみます。
技術的なポイントとして
・縦並びのレコードを横並びにトランスポーズ
・一次元配列を二次元配列にトレース
・ナンバリングをしながら配列に格納
・IDに対応したレコードへの処理
・配列の要素を文字列として連結しながら配列に格納
・配列の要素の合計を加算しながら配列に格納
・配列の要素の件数を加算しながら配列に格納
など、網羅しました。
ひとつひとつは初級の内容ですが、組み合わせると難度は高めです。
最も重要なポイントは”トレースの感覚を身に付けること”です。
(デバッグとトレースがごっちゃに解説されることが多いこの頃ですが)
配列変数の内容(要素)が処理に応じてどう変化してゆくのか、
確認しながらコーディングをチェックしていく作業過程、
これが出来るかどうかは配列変数を扱う上で必須と言ってもいい程、
非常に重要な技術的要素です。
VBAの場合は具体的に、
ブレークポイントを設けて実行したり、ステップモード実行したり、
しながら、ローカルウィンドウで、
基準となるインクリメント変数(一般に i や j などで表す変数)と
対応する配列変数の要素とが、どのように関連しながら変化していくのか、
ローカルウィンドウで確認していく、
という作業のことです。
実際に教えてみて感じたことですが、トレースを面倒臭がってやらない人
は、配列変数の習得に躓いて諦めてしまう人が殆どです。
上達の速い遅いもここら辺で決まってしまうようです。
(稀に天才的な方もいらっしゃるようですが、、、)
サンプルでは、ブレークポイントを設ける代りに、
何処まで処理したか都度都度
MsgBoxに表示して、セル範囲に都度出力して
変数の内容を視覚的に捉えられるようにしました。
続けて、Stopステートメントで処理を一時停止しているので
その状態でローカルウィンドウで変数の中身をチェックすれば
実践的なトレース、のトレーニングになる
ように書いています。
また、
Excel VBA ならではの、配列変数(二次元)を使う醍醐味というと、
セル範囲の値を、そのまま、配列として採り込んだり、
配列変数(二次元)として処理したデータを、
一気に纏めてセル範囲へ出力したり、
出来る、という特長のことになるかと思います。
今回は、
Variant型の変数に二次元配列を格納する、
ことも重要なポイントとして書いています。
(次の投稿でサンプルを提示します)
cj_mover様
私の拙い質問にこんなにも回答いただいて恐縮至極です。
仰る通り、どういうデータ、場面でどういうアウトプットをする時に配列が有効なのか、ということがイメージ出来ないでいたのですが、サンプルソースや沢山いただいた解説により理解が進められました。
基本サンプルの3点はこれは基本中の基本ですよね。
私なりに少しアレンジした形で何個かソース作って練習してみました。
明日からは、途中まで逆の流れと言うか、シートのデータを配列に取り込んで別シートに出力するソースも作っていきたいと思います。
メインのサンプルプログラムは私のPCで無事動かせています。
図解付きで進行がとても分かりやすいです。
また、Stop機能を使って経過を吟味しながらという手法も大切だと分かりました。
ローカルウィンドウなどの使い方にまだ慣れていないのですし、こちらのプログラムはまだ読みきれてない、理解し切れてないですが少しずつ進めていきたいと思います。
自分でしっかりソースが作れるまで取り組んでみます。
本当に有難う御座いました!
No.6
- 回答日時:
A列=あ行~J列=わ行 として五十音表を作ってみたけど・・
良く考えたら、五十音表って右から始まるよね(汗)。
・・・という状況(実際にあるかどうかわかりませんが)の時に
微妙に役に立つかもしれないサンプルです。
Sub Sample()
Dim myList() As String '配列を宣言
Dim myRow As Long, myColumn As Long
Dim i As Long, j As Long
' 行列数を確認
myRow = Cells(Rows.Count, 1).End(xlUp).Row
myColumn = Cells(1, Columns.Count).End(xlToLeft).Column
' 配列の行列を、データの行列数に拡張
ReDim myList(myRow, myColumn)
' セルの内容を順に配列に格納
For j = 1 To myColumn
For i = 1 To myRow
Cells(i, j).Select
myList(i, j) = Cells(i, j)
Next i
Next j
' 元の表の10行下に左右を入れ替えつつ、配列から取り出し
For j = myColumn To 1 Step -1
For i = 1 To myRow
Cells(i + 10, j).Select
Cells(i + 10, j) = myList(i, myColumn - j + 1)
Next i
Next j
End Sub
サンプルと呼べるほど大袈裟なものではありませんが、一応。
ステップインで動かすと、何かが掴めるかもしれません。
本当は二次元配列の開始位置は「0,0」なのですが・・
面倒なので「0,0」は無視して、「1,1」から使い始めているのが手抜きです。
まぁ要するに、他の方もおっしゃっていますが
「ワークシートのイメージそのまま」ですよ。
難しく考えるとどんどんハマりますから、簡単なところから徐々に行くのがミソです。
No.5
- 回答日時:
あらら、すみません。
No.4 です。long なのに int とか計算しても全く意味ありませんので、「and n = int(n)」という部分を削除してください。何度も失礼しました。No.4
- 回答日時:
1 次元の配列 2 つをまとめて書けば、2 次元の配列。
ベクトルを並べると行列になるのと同じですね。ショボいサンプルも載っけておきます。Sub ArraySample()
Dim a(3, 1) As String, prt As String
Dim i As Integer, n As Integer
a(0, 0) = "曲名"
a(0, 1) = "作曲者"
a(1, 0) = "運命"
a(1, 1) = "ベートーベン"
a(2, 0) = "アイネ・クライネ・ナハトムジーク"
a(2, 1) = "モーツァルト"
a(3, 0) = "幻想即興曲"
a(3, 1) = "ショパン"
For i = 1 To 3
prt = prt & vbCrLf & i & "……" & a(i, 0)
Next i
n = Application.InputBox(prompt:="曲名の番号を選んでください" & vbCrLf & prt, Title:="作曲者の表示", Type:=1)
If 1 <= n And n <= UBound(a, 1) And n = Int(n) Then
Range("a1").Value = a(0, 0)
Range("b1").Value = a(0, 1)
Range("a2").Value = a(n, 0)
Range("b2").Value = a(n, 1)
End If
Columns("a:b").AutoFit
End Sub
InputBoxもこのように作れるのですね。
とても参考になりました。
いろいろと応用が出来そうです。
ありがとうございました。
No.3
- 回答日時:
配列について概念としての理解を深めたいということでしたら、
こちらの解説が、解り易いと思います。
お求めの具体例、というのが、漠然として判りませんが、
こちらを読んでみて、それでももっと、例示が欲しい、
ということでしたら、補足してみてください。
配列研究室
http://www.clayhouse.jp/array/array.htm
No.2
- 回答日時:
ちょこちょこっと作ってみました。
A1セルにその月の初めの日
B1セルにその月の最後の日
その状態でこいつを実行すると、B4セルを頭にカレンダーを出力します。
Sub Macro()
Dim D_CAL(5, 7) As Integer
Dim I, J, D_DAY, D_CNT As Integer
D_DAY = Weekday(Range("A1").Value)
D_END = Day(Range("B1").Value)
D_CNT = 1
For I = 1 To 7
If D_DAY > I Then
D_CAL(1, I) = 0
Else
D_CAL(1, I) = D_CNT
D_CNT = D_CNT + 1
End If
Next
For J = 2 To 5
For I = 1 To 7
D_CAL(J, I) = D_CNT
D_CNT = D_CNT + 1
If D_CNT > D_END Then Exit For
Next
Next
Range("A3").Select
For I = 1 To 7
For J = 1 To 5
Selection.Offset(J, I).Value = D_CAL(J, I)
Next
Next
End Sub
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
許せない心理テスト
私は「あなたの目の前にケーキがあります。ろうそくは何本刺さっていますか」と言われ「12本」と答えたら…
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
VBAユーザーフォームのチェックボックスについて
Excel(エクセル)
-
Excelで範囲を可変して参照する関数を教えてください
Excel(エクセル)
-
エクセルで都道府県のリスト作成をしたいです。
Excel(エクセル)
-
-
4
セルをクリックすると付箋のようなものが表示されるのだが。
Excel(エクセル)
-
5
VBAでオブジェクトがありません、となってしまう
Visual Basic(VBA)
-
6
クイックアクセスツールバーに登録されたマクロについて
Excel(エクセル)
-
7
Excel:入力規制で選択された値によって他のセルの入力規制リストを変更する方法
Excel(エクセル)
-
8
ユーザーフォーム スクロールバー 非表示にしたい
Excel(エクセル)
-
9
新旧の数値の比較
Excel(エクセル)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
配列数式の解除
-
VBA 1次元配列を2次元に追加する
-
【MATLAB】任意の多次元配列か...
-
VBAで近似曲線の係数取得
-
subの配列引数をoptionalで使う...
-
特定のセル範囲で4文字以上入力...
-
配列に同じ値を入れる方法
-
VBAで配列をまるごとコピー
-
2次元動的配列の第一引数のみを...
-
AES暗号にて、AES_set_encrypt_...
-
CGIでカスタム配列でソート
-
for each の現在の配列ポインタ...
-
エクセルで最小値から0を除く方法
-
配列数式って何ですか??
-
fortran 渡す値について
-
OutlookVBAでサブフォルダ一括作成
-
[Excel2000_VBA] 型が一致しま...
-
Excel-VBAの配列「Public Const...
-
テキストボックスの表示
-
2つ以上の変数を比較して最大数...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
配列数式の解除
-
2つ以上の変数を比較して最大数...
-
VBA 1次元配列を2次元に追加する
-
VB6 配列を初期化したい
-
特定のセル範囲で4文字以上入力...
-
ListViewで、非表示列って作れ...
-
《エクセル2000》A列・B列の商...
-
配列変数の添字が範囲外ですと...
-
Excel-VBAの配列「Public Const...
-
subの配列引数をoptionalで使う...
-
for each の現在の配列ポインタ...
-
配列を任意の数値で埋める方法
-
Dim は何の略ですか?
-
VBのFunctionで、配列を引数...
-
配列内の内容を全て表示する方法
-
2次元動的配列の第一引数のみを...
-
Excel VBA配列をFunctionに渡す
-
VBA Match関数の限界
-
Array配列の末尾に追加したい。
-
AES暗号にて、AES_set_encrypt_...
おすすめ情報