
いつもお世話になっています。
配列にキーを格納した際の出力方法について教えてください。
【sheet1のB列】か、【sheet2のB列】終わりに【STB】とあった場合、下記の順番で【sheet3】にデータをまとめて転記したいです。
【sheet3】
A列・・・【sheet1】B列
B列・・・【sheet2】B列 ★sheet2
C列・・・【sheet1】D列
D列・・・【sheet1】E列
E列・・・【sheet2】AA列 ★sheet2
F列・・・【sheet1】K列
sheet1の参照範囲・・・A1~K300000
sheet2の参照範囲・・・A1~AA300000
sheet3の転記範囲
【Range(sh3.Cells(4, "A"), sh3.Cells(UBound(myKey) + 4, "F"))】
sheet3のA4から転記するため、範囲を上記の様に書いたのですが何も転記されず、
また、試しに範囲をF列からA列に変えてみたところ
他の列は転機されたのですが、A列はすべて空白でした。
【Range(sh3.Cells(4, "A"), sh3.Cells(UBound(myKey) + 4, "A"))】
なぜA列だけが空白になったり、なにも転記されなかったりするのでしょうか?
色々試したり検索しているのですがさっぱりわからず、
どうかアドバイスよろしくお願いします。
Sub SUMPLE()
Dim sh1 As Worksheet, sh2 As Worksheet, sh3 As Worksheet
Set sh1 = ThisWorkbook.Sheets("Sheet1")
Set sh2 = ThisWorkbook.Sheets("Sheet2")
Set sh3 = ThisWorkbook.Sheets("Sheet3")
Dim i As Long, j As Long, k As Long
Dim myKey, myR1, myR2, myR3, myAry
Dim myDic1 As Object
Set myDic1 = CreateObject("Scripting.Dictionary")
Set myR1 = Range(sh1.Cells(1, "A"), sh1.Cells(300000, "K")) '★Sheet1の範囲
Set myR2 = Range(sh2.Cells(1, "A"), sh2.Cells(300000, "AA")) '★Sheet2の範囲
With sh1
For i = 1 To 300000
If myR1(i, "B") Like "*STB" Or myR2(i, "B") Like "*STB" Then
myKey = myR1(i, "B") & "_" & myR2(i, "B") & "_" & myR1(i, "D") & "_" & myR1(i, "E") & "_" & myR2(i, "AA") & "_" & myR1(i, "K")
myDic1.Add (myKey), ""
End If
Next i
'★Sheet3に排出
myKey = myDic1.Keys
Set myR3 = Range(sh3.Cells(4, "A"), sh3.Cells(UBound(myKey) + 4, "F")) 'sheet3のA4から転記
For j = 0 To UBound(myKey)
myAry = Split(myKey(j), "_")
For k = 0 To UBound(myAry)
myR3(j + 1, k + 1) = myAry(k)
Next k
Next j
Range(sh3.Cells(4, "A"), sh3.Cells(UBound(myKey) + 4, "F")) = myR3
MsgBox "作成しました"
End With
End Sub
No.2ベストアンサー
- 回答日時:
こんにちは、#1です。
ちゃんと仕切り直しをして考えてみます。
ご質問のコードは、プロシージャの一部なのかもしれないと推測しましたが、
不明なところを推測しても仕方ないので、書かれているもので考えます。
概ね#1なのですが、)を打ち忘れたり、無い可能性のある1を指定したりと( UBound(Split(myKey(1), "_")) )
不備が多くありました。
Dim myKey, myR1, myR2, myR3, myAry 出来るだけ型宣言できるならした方がわかり易いかも
一理あるとは思いますが、変数名見ればわかるでしょ と 言われてしまうかもですね。
すでにお解りかと思いますが
Excel的に言うと、UBound(myR3,1)は行方向の大きさ UBound(myR3,2)は、列方向の大きさ ですが、
myR3が0から始まっていれば、myR3(0,0)は、UBound(myR3,1)=0 UBound(myR3,2)=0
myR3(j + 1, k + 1)で1から始めていれば、UBound(myR3,1)=1 UBound(myR3,2)=1
なので、1もいらないか?は、のちの処理によりますね。。
0から配列に入れていれば、
sh3.Range("A4").Resize(UBound(myR3, 1) + 1, UBound(myR3, 2) + 1) = myR3
で、sh3シートのA4セルになります。。
+1ならば、
あれば、sh3.Range("A4").Resize(UBound(myR3,1),UBound(myR3,2)で良い事になります。
ここ迄は、#1の訂正です。申し訳ありません。
表題の 配列にキーを格納した際の出力方法について は、
Resize(UBound(myR3,1),UBound(myR3,2) などを使うと判りやすいのではないでしょうか
いくつか気になる点がありますが、、は、
myR3の扱い、これは#1に示しました
myDic1.Add (myKey), "" これは、同じキーが存在した場合、エラーが返りませんか?
つまり、一意のキーしかないと言う事でしょうか?
下記のように重複キーワードを入れないようにしなくて良いのでしょうか?
If Not myDic1.Exists(myKey) Then myDic1.Add (myKey), ""
With sh1
この必要性が見当たりません。ですので、プロシージャの一部なのかもしれないと推測
myKey = myR1(i, "B") & "_" & myR2(i, "B") & "_" & myR1(i, "D") & "_" & myR1(i, "E") & "_" & myR2(i, "AA") & "_" & myR1(i, "K")
myKey = myDic1.Keys
これも、すこし乱暴な気がしますね
余計なことかもしれませんが、myR3を配列として変数名を変え下記のようなサンプルを書いてみました。
Sub SUMPLE()
Dim sh1 As Worksheet, sh2 As Worksheet, sh3 As Worksheet
Dim i As Long, j As Long, k As Long
Dim Keyword As String
Dim myR1 As Range, myR2 As Range
Dim myKey, myAry, myAry1
Dim myDic1 As Object
Set myDic1 = CreateObject("Scripting.Dictionary")
Set sh1 = ThisWorkbook.Sheets("Sheet1")
Set sh2 = ThisWorkbook.Sheets("Sheet2")
Set sh3 = ThisWorkbook.Sheets("Sheet3")
Set myR1 = Range(sh1.Cells(1, "A"), sh1.Cells(300000, "K")) '★Sheet1の範囲
Set myR2 = Range(sh2.Cells(1, "A"), sh2.Cells(300000, "AA")) '★Sheet2の範囲
For i = 1 To 300000
If myR1(i, "B") Like "*STB" Or myR2(i, "B") Like "*STB" Then
Keyword = myR1(i, "B") & "_" & myR2(i, "B") & "_" & myR1(i, "D") & "_" & myR1(i, "E") & "_" & myR2(i, "AA") & "_" & myR1(i, "K")
If Not myDic1.Exists(Keyword) Then
myDic1.Add (Keyword), ""
Else
'使用予定があるか分かりませんが存在キーの変更やItemの追加などに
End If
End If
Next i
'★Sheet3に排出
myKey = myDic1.Keys
' Set myR3 = Range(sh3.Cells(4, "A"), sh3.Cells(UBound(myKey) + 4, "F")) 'sheet3のA4から転記
If UBound(myKey) < 0 Then MsgBox "該当データがありません": Exit Sub
ReDim myAry1(UBound(myKey), UBound(Split(myKey(0), "_")))
For j = 0 To UBound(myKey)
myAry = Split(myKey(j), "_")
For k = 0 To UBound(myAry)
myAry1(j, k) = myAry(k)
Next k
Next j
' Range(sh3.Cells(4, "A"), sh3.Cells(UBound(myKey) + 4, "F")) = myR3
sh3.Range("A4").Resize(UBound(myAry1, 1) + 1, UBound(myAry1, 2) + 1).Value = myAry1
MsgBox "作成しました"
End Sub
No.1
- 回答日時:
こんばんは、
就寝前なので検証などをしていませんが、、走り書きで
いくつか気になる点がありますが、、
myKey = myR1(i, "B") & "_" & myR2(i, "B") & "_" & myR1(i, "D") & "_" & myR1(i, "E") & "_" & myR2(i, "AA") & "_" & myR1(i, "K")
がデータのすべて、、従ってmyAry = Split(myKey(j), "_")、 myR3(j + 1, k + 1) = myAry(k)が、きもとして
myR3はRange? 配列では無いのでしょうか?もし配列なら
Set myR3 = Range(sh3.Cells(4, "A"), sh3.Cells(UBound(myKey) + 4, "F")) 'sheet3のA4から転記 は不要
なぜなら、myR3(j + 1, k + 1) = myAry(k)で書き替えられているので、
ここは、配列として使い、
Redim myR3(UBound(myKey), UBound(Split(myKey(1), "_")))
UBound(Split(myKey(1), "_")) これ、成立していなければ 5でいいかな?
myR3(j + 1, k + 1) = myAry(k) の 1もいらないか?(上が5ならいらない)
Range(sh3.Cells(4, "A"), sh3.Cells(UBound(myKey) + 4, "F")) = myR3
は、多分こんな感じ、
sh3.Range("A4").Resize(UBound(myR3,1),UBound(myR3,2) = myR3
あ、それと Dim myKey, myR1, myR2, myR3, myAry
出来るだけ型宣言できるならした方がわかり易いかも
Set myR1 Set なので Rangeオブジェクト
myAry = は、配列(Variant)または省略可
纏めて代入しない場合は、配列サイズをReDimなどで設定
違っていたらごめんなさい。。。。
丁寧な解説ありがとうございます!
朝、最初の回答をもとに試行錯誤してたのですが
自分じゃ解決できず、後でゆっくりやろうと思ったら
さらに詳しく説明してくださって感動しました!
そして希望通りの形になってめちゃくちゃスゴイです!!
本当に感謝です!
ありがとうございました!!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
プロが教えるわが家の防犯対策術!
ホームセキュリティのプロが、家庭の防犯対策を真剣に考える 2組のご夫婦へ実際の防犯対策術をご紹介!どうすれば家と家族を守れるのかを教えます!
-
Excel、第一、第二、第三、の条件で同順を無くして順位確定する。 Excelのほぼ初心者です。 宜
Excel(エクセル)
-
EXCEL関数を作って頂きたいです。看護師です。専門外のため難しいです。
Excel(エクセル)
-
二つのリストを比べてまとめる方法について
Excel(エクセル)
-
4
エクセルの質問です
Excel(エクセル)
-
5
こんにちは。 朝質問させて頂きました。 Excelにて写メのような値(組み合わせ)がよく出ているか調
Excel(エクセル)
-
6
Excelの数式で、「ある特定の月日が含まれるかどうか」 ただし、年不問
Excel(エクセル)
-
7
並び順の違う2つのエクセル表
Excel(エクセル)
-
8
エクセル:Sheet2のC2にSheet1のE2を参照させたい。
Excel(エクセル)
-
9
エクセルについてお教え下さい。数値だけ入力すれば後ろに〝個〟と表示させるにはどうすればいいですか。例
Excel(エクセル)
-
10
エクセル関数教えて下さい。表の値以上であればそのセルを抽出
Excel(エクセル)
-
11
エクセル、 名前の定義に関数を使用すると参照できない
Excel(エクセル)
-
12
VBAで複数のブックからフィルターオプション
Excel(エクセル)
-
13
Excelで9秒50や11秒25などの数字が並んでいる中で秒"の前の数字だけを取り出すことはできま"
Excel(エクセル)
-
14
エクセル countif関数で、範囲を可変にするには
Excel(エクセル)
-
15
VBA重複チェック
Excel(エクセル)
-
16
いつもお世話になっております。 1行目に1ヶ月の日付が記入されていて(関数等は使わず1〜31まで手打
Excel(エクセル)
-
17
同じ条件で計算を繰り返す
Excel(エクセル)
-
18
エクセル マクロ? VBA? かなり難しいかもです
Excel(エクセル)
-
19
VBA 配列について
Excel(エクセル)
-
20
1セル入力したら他もささっと
Excel(エクセル)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
このカテゴリの人気Q&Aランキング
-
4
エクセルのIF関数で、文字が...
-
5
エクセル 週の合計計算
-
6
エクセル 表を大きく、紙いっ...
-
7
あるセルに特定の文字列を打つ...
-
8
エクセルのシートのコピーで出...
-
9
エクセルでマウスカーソルの形...
-
10
エクセル近似曲線(範囲指定)
-
11
Excelについて 写真の左の氏名...
-
12
エクセルの計算結果が0になって...
-
13
Excel 書式を関数で判断。
-
14
Excel 曜日の表示
-
15
excelで1つのセルだけを分割す...
-
16
エクセルの2ページ目の作り方
-
17
DATファイルをEXCELで開きたい
-
18
Excelで丸をつけたい
-
19
Excelを開くと、上画面に「サイ...
-
20
エクセルでセルが指定できない
おすすめ情報