Excel VBA質問箱 IV

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

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


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

【73761】表の比較 t−k 13/2/10(日) 15:38 質問[未読]
【73762】Re:表の比較 UO3 13/2/10(日) 19:22 発言[未読]
【73763】Re:表の比較 UO3 13/2/10(日) 19:51 発言[未読]
【73766】Re:表の比較 t−k 13/2/10(日) 22:56 発言[未読]
【73767】Re:表の比較 UO3 13/2/11(月) 6:46 発言[未読]
【75126】Re:表の比較 T-k 13/12/14(土) 0:02 質問[未読]
【75127】Re:表の比較 γ 13/12/14(土) 6:36 発言[未読]
【75133】Re:表の比較 T-k 13/12/17(火) 0:55 発言[未読]
【75134】Re:表の比較 γ 13/12/17(火) 6:35 発言[未読]
【75135】Re:表の比較 T-k 13/12/18(水) 0:28 発言[未読]
【75138】Re:表の比較 γ 13/12/18(水) 23:17 発言[未読]
【75141】Re:表の比較 T-k 13/12/20(金) 0:36 発言[未読]
【75143】Re:表の比較 γ 13/12/20(金) 7:16 発言[未読]
【75147】Re:表の比較 T-k 13/12/20(金) 23:50 お礼[未読]
【73768】Re:表の比較 UO3 13/2/11(月) 14:08 発言[未読]
【73770】Re:表の比較 t−k 13/2/12(火) 23:38 お礼[未読]
【73780】Re:表の比較 UO3 13/2/13(水) 19:30 発言[未読]
【81386】Re:表の比較 T-K 20/7/13(月) 23:33 質問[未読]
【81388】Re:表の比較 γ 20/7/14(火) 5:43 発言[未読]
【81393】Re:表の比較 T-K 20/7/14(火) 19:54 発言[未読]
【81394】Re:表の比較 γ 20/7/15(水) 9:15 回答[未読]
【81395】Re:表の比較 T-K 20/7/15(水) 17:45 お礼[未読]
【81396】Re:表の比較 マナ 20/7/15(水) 21:02 発言[未読]
【81398】Re:表の比較 マナ 20/7/15(水) 21:40 発言[未読]
【81397】Re:表の比較 マナ 20/7/15(水) 21:04 発言[未読]
【81399】Re:表の比較 T-K 20/7/15(水) 23:57 発言[未読]
【81400】Re:表の比較 マナ 20/7/16(木) 21:05 発言[未読]
【81410】Re:表の比較 T-K 20/7/23(木) 23:51 発言[未読]
【81412】Re:表の比較 マナ 20/7/24(金) 11:03 発言[未読]
【81415】Re:表の比較 マナ 20/7/24(金) 11:51 発言[未読]
【81429】Re:表の比較 T-K 20/7/29(水) 23:31 発言[未読]
【81433】Re:表の比較 マナ 20/7/30(木) 19:30 発言[未読]
【81434】Re:表の比較 マナ 20/7/30(木) 20:20 発言[未読]
【81435】Re:表の比較 T–K 20/8/1(土) 12:29 お礼[未読]

【73761】表の比較
質問  t−k  - 13/2/10(日) 15:38 -

引用なし
パスワード
   素人なのでわかりやすく教えてください

シート1とシート2の比較をしたいです

基本シート1のデータに変更したい
シート1のデータは毎日更新されます


シート1 1   2  3     4
    品番  品名  1/1   1/2 ←日にち行

A  ****   ****  100    300

B  ****   ****

C  ****   ****


シート 2
基本はシート1と同じ形 数量をシート2とシート1の品番と日が同じなら数量を転記
品番はシート2にない場合あり
ない場合シート1の品番のところに色を塗る処理をしたい

*シート2はデータを蓄積したいため 関数でのしょりではなく
値のみ入力したい

シート1に加工処理してデータを落とすまでできました(下記プログラム)
それ以降をどうしたらいいかわかりません
 Sub 開く()


Dim vri As Variant
Dim haifun
Dim rng As Range
Dim rng2 As Range
Dim rng3 As Range
Dim rng4 As Range


Application.ScreenUpdating = False

vri = Application.GetOpenFilename( _
filefilter:="テキストファイル,*.xls,", _
Title:="他のファイルを開く", _
MultiSelect:=False)

If vri = False Then
MsgBox "ファイルが選択されませんでした。", _
vbOKOnly + vbExclamation, "ファイル名の入力チェック"
Else

Workbooks.Open (vri)

End If


ActiveSheet.Select
Rows("1").Select

ActiveCell.AutoFilter field:=4, _
Criteria1:="*****"


Range("A1").CurrentRegion.Select
Selection.Copy


Workbooks("試作").Activate
Worksheets("データ取込").Activate
Range("A1").Select


ActiveCell.PasteSpecial (xlPasteValues)


Range("A:E").Select
Selection.Delete


Range("A1").End(xlToRight).Select

Range(ActiveCell, ActiveCell.End(xlDown)).Select
Selection.Delete

Range("A1").CurrentRegion.Select


Cells.Find(What:="合計", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
    xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
    , MatchByte:=False, SearchFormat:=False).Activate
    
    
 If ActiveCell = "合計" Then
 
Range(ActiveCell, ActiveCell.End(xlDown)).Select

Selection.Delete
Else
Range("A1").Activate


End If


For haifun = 1 To Range("A1").CurrentRegion.Rows.Count

Cells.Find(What:="-", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
    xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
    , MatchByte:=False, SearchFormat:=False).Activate


If ActiveCell = "-" Then

Range(ActiveCell, ActiveCell.End(xlDown)).Select

Selection.Delete
Else
Range("A1").Activate

End If
Next haifun

Range("A2").EntireRow.Insert
Range("C2").Select
ActiveCell.FormulaR1C1 = "=LEN(R[-1])"

Set rng = Range("c2")
Set rng2 = Range("XEX1").End(xlToLeft).Offset(1)

 Range("C2").AutoFill Destination:=Range(rng, rng2), Type:=xlFillDefault
  
Range("A3").EntireRow.Insert
Range("A3").EntireRow.Insert

Range("d3").Select


  Range("D3").Select


Selection.FormulaR1C1 = "=IF(OR(R[-1]=1,R[-1]=2),R[-2]C[-1]+1,R[-2])"

Range("E3").Select
Selection.FormulaR1C1 = "=IF(OR(R[-1]=1,R[-1]=2),C[-1]+1,R[-2])"

Set rng3 = Range("E3")
Set rng4 = Range("XEX1").End(xlToLeft).Offset(2)

Range("e3").AutoFill Destination:=Range(rng3, rng4), Type:=xlFillDefault

Rows("3:3").Select
  Selection.NumberFormatLocal = "yyyy/m/d;@"


Range("d3").Select
Range(ActiveCell, ActiveCell.End(xlToRight)).Select
Selection.Copy
Range("D4").PasteSpecial xlPasteValues
Range("D4").Select
Rows("4:4").Select
  Selection.NumberFormatLocal = "yyyy/m/d;@"

Range("D4").Select


Range(ActiveCell, ActiveCell.End(xlToRight)).Select
Selection.Copy
Range("D1").Select
Range("D1").PasteSpecial xlPasteValues

Rows("1:1").Select
 Selection.NumberFormatLocal = "yyyy/m/d;@"


Rows("2:4").EntireRow.Delete


 Rows("1:1").Select
  Selection.NumberFormatLocal = "m/d;@"
 
 Rows("1:1").Select
  With Selection
    .HorizontalAlignment = xlRight
    .WrapText = False
    .Orientation = 0
    .AddIndent = False
    .IndentLevel = 0
    .ShrinkToFit = False
    .ReadingOrder = xlContext
    .MergeCells = False
  End With
Rows("2:2").Select
Selection.Insert
Range("C2").Select
Range("c2").Formula = "=VALUE(C1)"
Range("C2").Select


Set rng = Range("c2")
Set rng2 = Range("XEX1").End(xlToLeft).Offset(1)


Range("C2").AutoFill Destination:=Range(rng, rng2), Type:=xlFillDefault


Range("C2").Select

Rows("3:3").Select
Selection.Insert
Range("C2").Select
Range("c2").Copy
Range("C3").PasteSpecial xlPasteValues

Range("C3").AutoFill Destination:=Range(Range("C3"), Range("xex1").End(xlToLeft).Offset(2)), Type:=xlFillDefault


Range("C3").Select
  Range(Selection, Selection.End(xlToRight)).Select
  Selection.Copy

Range("c1").Select

Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
    :=False, Transpose:=False

Rows("2:3").Delete

Range(Range("C2"), Range("XEX1").End(xlToLeft).End(xlDown)).Select
Selection.NumberFormatLocal = "G/標準"


Application.ScreenUpdating = True
Worksheets("メニュー画面").Activate


MsgBox "データ取り込み終了"


End Sub

よろしくご指導お願いします。

【73762】Re:表の比較
発言  UO3  - 13/2/10(日) 19:22 -

引用なし
パスワード
   ▼t−k さん:

こんばんは

シート2にのみあってシート1にない場合はどうしましょう?
それと・・・
最近、いろんな板でこの表示がでているので気になっているのですが
シートの縦方向は1,2,3,・・・という行番号。
横方向は A,B,C,・・・という列記号。
もちろん、表示方式の設定によっては横方向も 1,2,3,・・・という表示にはなりますが
少なくとも縦方向が A,B,C,・・・という表示にはなりませんよね?

それと、縦方向の A,B,C,・・・が 1,2,3・・・の表記間違いだとして
1行目はタイトル行なんですよね?
(アップされたサンプルで A とある、その行がデータ行になっていますが?)

【73763】Re:表の比較
発言  UO3  - 13/2/10(日) 19:51 -

引用なし
パスワード
   ▼t−k さん:

こんばんは

>素人なのでわかりやすく教えてください

わかりやすくはないと思いますが・・・
必要なら、主要なところにコメントをつけますけど、とりあえず。

アップされたコードは全く読んでいません。
提示されたレイアウトだけを見て処理しています。

Sheet2に転記できなかったSheet1のセルに色づけするとともに、
Sheet2にしか存在しなかったものについてもSHeet2側のセルに色づけしています。

Sub Sample()
  Dim fSh As Worksheet
  Dim tSh As Worksheet
  Dim fDic As Object
  Dim tDic As Object
  Dim c As Range
  Dim dt As Double
  Dim com As String
  Dim dKey As Variant
  
  Application.ScreenUpdating = False
  
  Set fDic = CreateObject("Scripting.Dictionary")
  Set tDic = CreateObject("Scripting.Dictionary")

  Set fSh = Sheets("Sheet1")
  Set tSh = Sheets("Sheet2")
  
  fSh.Cells.Interior.ColorIndex = xlNone
  tSh.Cells.Interior.ColorIndex = xlNone
  
  With fSh.Range("A1").CurrentRegion
    For Each c In .Offset(1, 2).Resize(.Rows.Count - 1, .Columns.Count - 2)
      dt = fSh.Cells(1, c.Column).Value2
      com = fSh.Cells(c.Row, "A").Value
      fDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))
    Next
  End With
  
  With tSh.Range("A1").CurrentRegion
    For Each c In .Offset(1, 2).Resize(.Rows.Count - 1, .Columns.Count - 2)
      dt = tSh.Cells(1, c.Column).Value2
      com = tSh.Cells(c.Row, "A").Value
      tDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))
    Next
  End With
      
  'Sheet1からSheet2への転記
  
  For Each dKey In fDic
    If tDic.exists(dKey) Then
      Range(tDic(dKey)(1)).Value = Range(fDic(dKey)(1)).Value
    Else
      Range(fDic(dKey)(1)).Interior.ColorIndex = 3
    End If
  Next
  
  'Sheet2 にしか存在しない項目の色つけ
  
  For Each dKey In tDic
    If Not fDic.exists(dKey) Then Range(tDic(dKey)(1)).Interior.ColorIndex = 3
  Next
  
  tSh.Activate
  Application.ScreenUpdating = True
  MsgBox "転記完了"
  
End Sub

【73766】Re:表の比較
発言  t−k  - 13/2/10(日) 22:56 -

引用なし
パスワード
   ▼UO3 さん:
>▼t−k さん:
>
>こんばんは
>
>>素人なのでわかりやすく教えてください
>
>わかりやすくはないと思いますが・・・
>必要なら、主要なところにコメントをつけますけど、とりあえず。
>
>アップされたコードは全く読んでいません。
>提示されたレイアウトだけを見て処理しています。
>
>Sheet2に転記できなかったSheet1のセルに色づけするとともに、
>Sheet2にしか存在しなかったものについてもSHeet2側のセルに色づけしています。
>
>Sub Sample()
>  Dim fSh As Worksheet
>  Dim tSh As Worksheet
>  Dim fDic As Object
>  Dim tDic As Object
>  Dim c As Range
>  Dim dt As Double
>  Dim com As String
>  Dim dKey As Variant
>  
>  Application.ScreenUpdating = False
>  
>  Set fDic = CreateObject("Scripting.Dictionary")
>  Set tDic = CreateObject("Scripting.Dictionary")
>
>  Set fSh = Sheets("Sheet1")
>  Set tSh = Sheets("Sheet2")
>  
>  fSh.Cells.Interior.ColorIndex = xlNone
>  tSh.Cells.Interior.ColorIndex = xlNone
>  
>  With fSh.Range("A1").CurrentRegion
>    For Each c In .Offset(1, 2).Resize(.Rows.Count - 1, .Columns.Count - 2)
>      dt = fSh.Cells(1, c.Column).Value2
>      com = fSh.Cells(c.Row, "A").Value
>      fDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))
>    Next
>  End With
>  
>  With tSh.Range("A1").CurrentRegion
>    For Each c In .Offset(1, 2).Resize(.Rows.Count - 1, .Columns.Count - 2)
>      dt = tSh.Cells(1, c.Column).Value2
>      com = tSh.Cells(c.Row, "A").Value
>      tDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))
>    Next
>  End With
>      
>  'Sheet1からSheet2への転記
>  
>  For Each dKey In fDic
>    If tDic.exists(dKey) Then
>      Range(tDic(dKey)(1)).Value = Range(fDic(dKey)(1)).Value
>    Else
>      Range(fDic(dKey)(1)).Interior.ColorIndex = 3
>    End If
>  Next
>  
>  'Sheet2 にしか存在しない項目の色つけ
>  
>  For Each dKey In tDic
>    If Not fDic.exists(dKey) Then Range(tDic(dKey)(1)).Interior.ColorIndex = 3
>  Next
>  
>  tSh.Activate
>  Application.ScreenUpdating = True
>  MsgBox "転記完了"
>  
>End Sub


T-Kですさっそく回答ありがとうございます

Dictionary 配列等使わないとむりかなとはおもっていましたが
正直苦手な領域(理解しきれていない)為困っていました
コードでわからない部分があるため教えてください

 For Each c In .Offset(1, 2).Resize(.Rows.Count - 1, .Columns.Count - 2)
*行列範囲の指定なのは理解できるのですが それぞれ-1、-2する理由が不明
です
fDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))
配列を格納しているのは理解できるのですが VBA.Arrayの部分
とValueとAddresを行と列で言い方を変えてる部分が理解できません

日付の部分でVALUE2と表記してる部分も理解できていません
勉強の意味も含めて教えていただけないでしょうか?

【73767】Re:表の比較
発言  UO3  - 13/2/11(月) 6:46 -

引用なし
パスワード
   ▼t−k さん:

おはようございます

>行列範囲の指定なのは理解できるのですが それぞれ-1、-2する理由が不明です

たとえばアップされて表の例でいいますと

A1 のCurrentRegion は A1:D4 ですね。(4行4列)
で、この中の いわゆる データが入っているリストの領域は C2:D4(3行2列) になりますね。

.Offset(1, 2)  == Offset(行方向の移動行数,列方向の移動列数)

これで、CurrentRegion領域を 1 つ下、2つ右に変化させます。
結果は C2:F5 になります。(4行4列)

.Resize(.Rows.Count - 1, .Columns.Count - 2) == Resize(変更後の行数,変更後の列数)

これで、上で変化させた領域 C2:F5 という 4行4列の領域に対して
行を、その行数4から 1を引いて 3行に、列を、その列数4から 2 を引いて 2列に変化させます。

ですから、結果は C2:D4 の 3行2列の領域になります。

>VBA.Arrayの部分とValueとAddresを行と列で言い方を変えてる部分が理解できません

まず、Array関数についてはヘルプも一読しておいてください。
Array(○○○,□□) は ○○○ と □□□ の 2つの要素を持った一次元配列を
生成します。通常、VBA. とつけずに使う例が多いと思いますが、これだと、できあがった配列の
LBoundが、もし、別途 Option Base 1 の記述が、このモジュールにあれば 1 になってしまいます。
コードの中では、最初の要素番号を 0 として処理しています。VBA. とつければ Option Base の記述の
有無にかかわらず、LBound が 0 で作られますので安心して処理できます。

で、VBA.Array(c.Value, c.Address(External:=True))

c.Value と c.Address(External:=True) の2つの値を配列の要素にしているわけです。
仮に c が アップされた例の C2 だったとします。
そうしますと、最初の要素 c.Value は 100 ですね。(セルの値)
で、c.Address(External:=True) は、そのセルのアドレスですが External:=True とすることで
単に "C2" ではなく、どのブックのどのシートのC2 だというアドレス文字列が格納されます。
ですから、あとからこのセルを Range(そのアドレス文字列) で参照することが可能です。

>日付の部分でVALUE2と表記してる部分も理解できていません

日付は、見た目 yyyy/mm/dd ですが、内容としては小数点付きのシリアル値というのは
ご存じでしょうか。
たとえば、今日 2013/2/11 は 41316 です。また現在の時刻は 41316.27901 あたりです。
Value2 には、日付セルの場合、このシリアル値を格納してくれます。
日付の検索は、けっこうやっかいなので、私はもっぱら、Value2 を使います。

【73768】Re:表の比較
発言  UO3  - 13/2/11(月) 14:08 -

引用なし
パスワード
   ▼t−k さん:

追記です。
最後の質問ですが、今回の場合は、Value でも問題はないですが。

【73770】Re:表の比較
お礼  t−k  - 13/2/12(火) 23:38 -

引用なし
パスワード
   ▼UO3 さん:
>▼t−k さん:
>
>追記です。
>最後の質問ですが、今回の場合は、Value でも問題はないですが。

T-Kです
返事遅くなりました
とりあえず自分の求めていた形に近くなりました
配列にいれた数字の数が変化した場合も数字の色を変化させたかったのですが
そこまでは高望みだとおもうのでこれでOKにしたいと思います。
ありがとうございます。
これからもいろいろと教えてください。

【73780】Re:表の比較
発言  UO3  - 13/2/13(水) 19:30 -

引用なし
パスワード
   ▼t−k さん:

>配列にいれた数字の数が変化した場合も数字の色を変化させたかったのですが
>そこまでは高望みだとおもうのでこれでOKにしたいと思います。

配列の数字が変わったらということじゃなく、セルの数字が変わったらということだと思いますが
Sheet1,Sheet2のセルに値等の変化があったら自動的にこの処理を行うことは可能ですよ。
どんな変更でも、その都度実行されますから、これでは困るということになるかもしれませんが。

【75126】Re:表の比較
質問  T-k  - 13/12/14(土) 0:02 -

引用なし
パスワード
   fDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))

今も仕事で利用させて頂いていますありがとうございます
処理出来ていることで理解してないのに無理やり納得させていました
自分の悪い癖で申し訳ありません解説していただいたんですが
もう一度教えて頂けないでしょうか?

fDicはオブジェクト型のDictionary(辞書)の配列に一次元配列Arrayの要素を代入
という解釈でいいと思うのですが?

片方はObject型で片方はVariant型で型が違うのですがOKなのでしょうか?
fDicの要素はデータの入力されている行の変数と列の変数を連結させたものにArray
で指定した要素(行、列で指定した以外の値とそのアドレス)を代入という解釈
でいいのでしょうか? 
この状態のイメージがいまいちつかめない為Sheet2~Sheet1に転記の所も
少し解釈に違和感があります。

【75127】Re:表の比較
発言  γ  - 13/12/14(土) 6:36 -

引用なし
パスワード
   こんにちは。

Dictionaryというのは、Keyと値の組み(対応関係)を管理する容れ物です。

> fDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))
この例では、
品番に日付数値を連結した文字列 を Key とし、
値とアドレス文字列からなる配列 を 値 とした対応関係です。
 
 "ABC41621" ---> Array(100,"[Book1]Sheet1!$A$1")
 "ABC41622" ---> Array(200,"[Book1]Sheet1!$A$2")
 "ABC41623" ---> Array(300,"[Book1]Sheet1!$A$3")

> 片方はObject型で片方はVariant型で型が違うのですがOKなのでしょうか?
型に注目されているようですが、
・Dictionaryという、対応関係を入れた容れ物そのものがObject型 ということと
・Dictionaryの値が、配列が格納されたVariant型 ということは、
なんら矛盾することなく成立することですよね。

何事もおろそかにしない姿勢はすばらしいと思いました。
上記の説明で、Dictionaryの考え方を理解する参考になるでしょうか。

【75133】Re:表の比較
発言  T-k  - 13/12/17(火) 0:55 -

引用なし
パスワード
   ▼γ さん:
>こんにちは。
>
>Dictionaryというのは、Keyと値の組み(対応関係)を管理する容れ物です。
>
>> fDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))
> この例では、
> 品番に日付数値を連結した文字列 を Key とし、
> 値とアドレス文字列からなる配列 を 値 とした対応関係です。
> 
> "ABC41621" ---> Array(100,"[Book1]Sheet1!$A$1")
> "ABC41622" ---> Array(200,"[Book1]Sheet1!$A$2")
> "ABC41623" ---> Array(300,"[Book1]Sheet1!$A$3")
>
>> 片方はObject型で片方はVariant型で型が違うのですがOKなのでしょうか?
>型に注目されているようですが、
> ・Dictionaryという、対応関係を入れた容れ物そのものがObject型 ということと
> ・Dictionaryの値が、配列が格納されたVariant型 ということは、
>なんら矛盾することなく成立することですよね。
>
>何事もおろそかにしない姿勢はすばらしいと思いました。
>上記の説明で、Dictionaryの考え方を理解する参考になるでしょうか。

早速の返事ありがとうございます

考えが整理できていないなかった為返事遅くなりました。申し訳ありません
以前解説していただいた部分である程度上記の部分と同じイメージ
でした

とりあえず的外れの言論でしたら最初に謝ります
自分なりにわからない部分を整理してみます


1. fDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))
上記文の中の
fDic(com & dt)の部分本来KeyやItemを追加する場合

Addメソッド等でKeyやItemを格納すると思うのですが 
上記文はすでにkeyが格納されているところが不明

2.com & dtでA列の値と1行目の日付け数値(シリアル値)の連結したものを
KeyとしDictionaryに格納、ArrayでAddressと
値の要素を格納して対応関係を表すまではわかるのですが

パソコン自体どのようにこれが対応していると判断しているかの
イメージがつかめていません
一つ一つのデータで考えてしまっているのでおかしな解釈なのかもしれませんが・・・?
配列が苦手なのはこの理解の部分です

3.for each dkey in fdic
if fdic.exists(dkey)then
range(tdic(dkey)(1)).value=range(tdic(dkey)(1).value
変数dkeyがある場合Sheet2~shhet1へ転記
簡単にはそんな文だと思いますが

この部分のRange(Tdic(dkey)(1))の"(1)"の部分がわかりません

【75134】Re:表の比較
発言  γ  - 13/12/17(火) 6:35 -

引用なし
パスワード
   >Dictionaryというのは、Keyと値の組み(対応関係)を管理する容れ物です。
と書きました。
変数key,valを使って書きますが、
Dictionaryにこの組を追加する際の書き方として、
   dic.Add key,val  '  ---- (1)
   dic(key) = val   '  ---- (2)
の二つの方式が利用できます。

ただし、既にkeyというキーがあるときの振る舞いが異なります。
・ (1)はエラーになり、
・ (2)はエラーにならず、keyに対応するdicの値が新たに valに変わります。

ヘルプでは(1)が採用されていますが、実務的には(2)を使う場面が多いです。
というのは、Dictionaryの使い方として、
普通は、重複を除いてキーを集めるなどという使い方が多いので、
その場合は、存在するかどうかは構わずに、
単に dic(key) = Empty などとすればいいわけです。
逐一、存在をチェックする必要はありません。
Emptyを上書きしていくことでも問題が無いわけです。

同じkeyの個数をカウントするなどという場合も、
単に
  dic(key) = dic(key) + 1
とすることが多いです。
( 単に、dic.Add key, dic.Item(key) + 1 とするとエラーになるので注意が必要です。)

-----------
2.
> パソコン自体どのようにこれが対応していると判断しているかの
> イメージがつかめていません
Dictionaryオブジェクトの実装には、Hash テーブルというものが使われていて、
検索スピードを上げる工夫がされているそうですが、
それは気にする必要はありません。

Dictionaryのイメージは、単に、
  二つのものの対応関係を管理する容れ物
ということで良いと思います。

一次元の配列は、
  0  --> ary(0) 
  1  --> ary(1)
  2  --> ary(2)
のように、"整数をキーにして"対応関係を持っていることが特徴です。
参照するときは、整数を指定します。ary(0)のように。

Dictionaryの場合は、整数に限らず文字列などをキーにして、
値を保存したり、キーを指定して対応する値を取り出すことができるのです。
通常、keyは文字列であることが多いですね。
 "aaa" --> 対応する値
 "bbb" --> 対応する値
のような対応関係です。

一方、Dictionayの値に使えるのは、
数値でも文字列でも、今回のように配列でも、Excelのオブジェクトでも
なんでもOKです。
場合によっては dictionaryオブジェクトを値に持つdictionaryすら作れます。

要するに、Dictionaryは、
  整数に限らないkeyを指定して、それに対応するなんらかの値を取り出すことができる仕組み、
と考えれば良いわけです。

-------------------
3.
今回の例では、値そのものに配列が使われています。
> この部分のRange(Tdic(dkey)(1))の"(1)"の部分がわかりません

fDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))
とDictionryを構成した時の
Range(tDic(dKey)(1)).Value
の解釈ですが、
  ・ tDic(dKey) の部分で、Dictionaryの値を取り出しています。
   それは、VBA.Array(c.Value, c.Address(External:=True))のような配列です。
   つまり、要素が二つのArrayです。
   
  ・ (1)というのは、そのArrayの2番目の要素という意味です。(0が1番目です)
   したがって、
   tDic(dKey)(1) は、
   "[Book1]Sheet1!$A$1" というような、セルc のアドレスを示す文字列 です。
結局、
Range(tDic(dKey)(1)).Value は、
Range("[Book1]Sheet1!$A$1").Value というような内容になります。
---------------------
何かあれば追加質問して下さい。  

【75135】Re:表の比較
発言  T-k  - 13/12/18(水) 0:28 -

引用なし
パスワード
   ▼γ さん:
>>Dictionaryというのは、Keyと値の組み(対応関係)を管理する容れ物です。
>と書きました。
>変数key,valを使って書きますが、
>Dictionaryにこの組を追加する際の書き方として、
>   dic.Add key,val  '  ---- (1)
>   dic(key) = val   '  ---- (2)
>の二つの方式が利用できます。
>
>ただし、既にkeyというキーがあるときの振る舞いが異なります。
>・ (1)はエラーになり、
>・ (2)はエラーにならず、keyに対応するdicの値が新たに valに変わります。
>
>ヘルプでは(1)が採用されていますが、実務的には(2)を使う場面が多いです。
>というのは、Dictionaryの使い方として、
>普通は、重複を除いてキーを集めるなどという使い方が多いので、
>その場合は、存在するかどうかは構わずに、
>単に dic(key) = Empty などとすればいいわけです。
>逐一、存在をチェックする必要はありません。
>Emptyを上書きしていくことでも問題が無いわけです。
>
>同じkeyの個数をカウントするなどという場合も、
>単に
>  dic(key) = dic(key) + 1
>とすることが多いです。
>( 単に、dic.Add key, dic.Item(key) + 1 とするとエラーになるので注意が必要です。)
>
>-----------
>2.
>> パソコン自体どのようにこれが対応していると判断しているかの
>> イメージがつかめていません
>Dictionaryオブジェクトの実装には、Hash テーブルというものが使われていて、
>検索スピードを上げる工夫がされているそうですが、
>それは気にする必要はありません。
>
>Dictionaryのイメージは、単に、
>  二つのものの対応関係を管理する容れ物
>ということで良いと思います。
>
>一次元の配列は、
>  0  --> ary(0) 
>  1  --> ary(1)
>  2  --> ary(2)
>のように、"整数をキーにして"対応関係を持っていることが特徴です。
>参照するときは、整数を指定します。ary(0)のように。
>
>Dictionaryの場合は、整数に限らず文字列などをキーにして、
>値を保存したり、キーを指定して対応する値を取り出すことができるのです。
>通常、keyは文字列であることが多いですね。
> "aaa" --> 対応する値
> "bbb" --> 対応する値
>のような対応関係です。
>
>一方、Dictionayの値に使えるのは、
>数値でも文字列でも、今回のように配列でも、Excelのオブジェクトでも
>なんでもOKです。
>場合によっては dictionaryオブジェクトを値に持つdictionaryすら作れます。
>
>要するに、Dictionaryは、
>  整数に限らないkeyを指定して、それに対応するなんらかの値を取り出すことができる仕組み、
>と考えれば良いわけです。
>
>-------------------
>3.
>今回の例では、値そのものに配列が使われています。
>> この部分のRange(Tdic(dkey)(1))の"(1)"の部分がわかりません
>
>fDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))
>とDictionryを構成した時の
>Range(tDic(dKey)(1)).Value
>の解釈ですが、
>  ・ tDic(dKey) の部分で、Dictionaryの値を取り出しています。
>   それは、VBA.Array(c.Value, c.Address(External:=True))のような配列です。
>   つまり、要素が二つのArrayです。
>   
>  ・ (1)というのは、そのArrayの2番目の要素という意味です。(0が1番目です)
>   したがって、
>   tDic(dKey)(1) は、
>   "[Book1]Sheet1!$A$1" というような、セルc のアドレスを示す文字列 です。
>結局、
>Range(tDic(dKey)(1)).Value は、
>Range("[Book1]Sheet1!$A$1").Value というような内容になります。
>---------------------
>何かあれば追加質問して下さい。


1.返事いただきありがとうございます  
Key,Itemの追加の仕方が2通りあるのは初めて知りました
このあたりは勉強になりましたありがとうございます。納得です
2.
一番自分の中で難解だったパソコン処理のイメージですが
行列を連結した文字列をkeyとしForEachステートメントで自動でアドレスを辞書に追加していくイメージ
たとえば変数CががC12ならその交差している行と列の連結がKeyになる
と思うのですがこの1文でその解釈をパソコンがしてくれているイメージでいいんでしょうか



3.
後(1)は要素番号の指定だったんですね
文の書き方はこの書き方なんですね?

【75138】Re:表の比較
発言  γ  - 13/12/18(水) 23:17 -

引用なし
パスワード
   > たとえば変数CががC12ならその交差している行と列の連結がKeyになる
> と思うのですがこの1文でその解釈をパソコンがしてくれているイメージでいいんでしょうか
> ?
それでよいと思います。

参考までにお聞きしますが、
     For Each c In .Offset(1, 2).Resize(.Rows.Count - 1, .Columns.Count - 2)
      dt = tSh.Cells(1, c.Column).Value2
      com = tSh.Cells(c.Row, "A").Value
      tDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))
    Next
の3行の意味は理解されているのですよね。

こうしうことがすべきだと思うのだけど、
それはどこで実行しているのかな、
といったことがもしあるなら、
その「すべきこと」を教えてください。

なお、必要もないのに全文引用するのはやめたほうが良いと思います。

【75141】Re:表の比較
発言  T-k  - 13/12/20(金) 0:36 -

引用なし
パスワード
   ▼γ さん:
>> たとえば変数CががC12ならその交差している行と列の連結がKeyになる
>> と思うのですがこの1文でその解釈をパソコンがしてくれているイメージでいいんでしょうか
>> ?
>それでよいと思います。
>
>参考までにお聞きしますが、
>     For Each c In .Offset(1, 2).Resize(.Rows.Count - 1, .Columns.Count - 2)
>      dt = tSh.Cells(1, c.Column).Value2
>      com = tSh.Cells(c.Row, "A").Value
>      tDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))
>    Next
>の3行の意味は理解されているのですよね。
>
>こうしうことがすべきだと思うのだけど、
>それはどこで実行しているのかな、
>といったことがもしあるなら、
>その「すべきこと」を教えてください。
>
>なお、必要もないのに全文引用するのはやめたほうが良いと思います。


返事ありがとうございます


3行の意味は理解されているのですよね。
>
 For Each c In .Offset(1, 2).Resize(.Rows.Count - 1, .Columns.Count - 2)
>      dt = tSh.Cells(1, c.Column).Value2
>      com = tSh.Cells(c.Row, "A").Value
>      tDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))
>    Next

上記意味はKey以外のすべての配列要素(変数C)に対して繰り返し処理
変数dtに日にちの入力された行範囲の値(シリアル値)を代入
変数comに文字列データの入力してある列範囲の値を代入(A列)
Dictionaryオブジェクト変数tdicに変数Comとdtを連結した値をKeyとし変数Cの値と変数Cのアドレスを配列要素とし代入
*ComとdtがKeyになっているのは今回教えてもらって理解しました


自分の理解はこんな感じです


こうしうことがすべきだと思うのだけど、
>それはどこで実行しているのかな、
>といったことがもしあるなら、
>その「すべきこと」を教えてください。
>
すべきことはできていてどこの文で実行しているか
なんとなく文をみて
予測できます
変数 配列等の解釈に少し不安な部分があり不躾な質問ばかり
してしまい申し訳ありません


>なお、必要もないのに全文引用するのはやめたほうが良いと思います

必要か必要でないかと言われたとき自分のしている仕事の効率化
をするためにこのときはどうしても必要でした
今もそうですが知識と経験が足りなくここまで難しい文
をオリジナルで作れるほどのスキルがないです
道理的にもいけないことは承知していますが
このままではいけないと思い直し恥をしのんで教えを乞うています

【75143】Re:表の比較
発言  γ  - 13/12/20(金) 7:16 -

引用なし
パスワード
   Dictionaryは結構便利なものなので、
実際に活用されると、一層理解が深まると思います。
また、他の回答にもよく出てきますので、
活用例をいくつか調べるとよろしいかと思います。

--------
なお書きとして書いた、全文引用に関する私の発言を
誤解されているようですので、説明しておきます。

ここで発言する際に、前の発言をすべて引用してから
追記されていますが、その必要はないでしょう、という意味です。
仕事に必要な質問かどうかなどということは、全く申し上げていません。
もちろん必要だから質問されていることは理解しています。
相当時間が経っているのに、疑問の解消に努めている点は、
すばらしいと思っています。

73766,75133,75135,75141などいずれも全文引用していますが、
特に75135など長文の前発言をそのまま全文引用しなくても、
相手に、そして読んでいる方に十分伝わります。
かえって冗長になって、ムダな全文引用になっているということです。
一回ごとのメールのやりとりではなく、
発言順に読んでいける掲示板の形式なので、
その重複感が目立つと思います。
必要な箇所だけ引用して、それにコメントすれば済むのです。

個人的な見解で細かいこと言うな、と思われるかも知れませんが、
実はこれはかなり一般的な話として言われていることです。
例えば、下記を参照してください。
ht★tp://www.hyuki.com/writing/techask.html#reply
(urlの記載は禁止されているようなので、あえて★をつけています。
 ★をとったものをurlとして、ブラウザーに入力して下さい。)
できるだけこうしたことに配慮したほうがご自身にとっても得です。

【75147】Re:表の比較
お礼  T-k  - 13/12/20(金) 23:50 -

引用なし
パスワード
   返信ありがとうございます

今回初めて理解したところもありいろいろ
勉強になりました
また質問はすると思いますが
自分なりにいろいろ過去の投稿等参考に理解を深めたいと思います。

引用の件

了解いたしました自分の勘違いで申し訳ありません
でした以後きおつけます

【81386】Re:表の比較
質問  T-K  - 20/7/13(月) 23:33 -

引用なし
パスワード
   以前この題目で問い合わせした、T-Kです。
Dictionaryにて値をKeyにして重複のない値をエクセルへ出力処理するやり方を
教えていただきました。ありがとうございました。

またおしえていただきたいのは、この内容の処理を配列でも
表現が可能なのでしょうか?

セルの値を配列に格納->それを加工してシートに出力という流れだと思いますが、
Dictionaryのように文字をKeyとできないこと 重複していても格納されてしまうこと等考えると、Dictionaryのほうが使い勝手はいいように思いますが、
もしその点で分かる方いらしたら教えてください。

【81388】Re:表の比較
発言  γ  - 20/7/14(火) 5:43 -

引用なし
パスワード
   7年以上前のものですね。懐かしい。

さて、
Dictionaryを使わず、配列で実現できないか、
と言う質問に至った経緯を、逆に、もう少し教えていただきたいですね。

【81393】Re:表の比較
発言  T-K  - 20/7/14(火) 19:54 -

引用なし
パスワード
   返信ありがとうございます。
一番の理由は、配列を理解するため。 
もう一つは、dictionaryのこのプラグラム
を仕事で今も使用しているが、
使用していくなかで、処理が重くなってきた為です。 
データを蓄積してけば、重くなるのは理解できます。
少しでも軽く処理が出来ないかと考えたときに、
配列はどうなのか、と考えました。
配列を登録してセルに出力はできますが、
dictionaryのように、keyに対してセルのアドレスに
値を出力する方法がわかりません。

お手数お掛けして申し訳ありません。
よろしくお願い致します。

【81394】Re:表の比較
回答  γ  - 20/7/15(水) 9:15 -

引用なし
パスワード
   さて、通常の配列は、整数のインデックスを持ちますが、
このケースでは、
 "ABC41621" ---> Array(100,"[Book1]Sheet1!$A$1")
 "ABC41622" ---> Array(200,"[Book1]Sheet1!$A$2")
 "ABC41623" ---> Array(300,"[Book1]Sheet1!$A$3")
という対応関係に関する情報が必要になります。

これを配列で管理しようとしたら、
 0番目のindexに Array(100,"[Book1]Sheet1!$A$1") を持たせ
 1番目のindexに Array(200,"[Book1]Sheet1!$A$2") を持たせ
 2番目のindexに Array(300,"[Book1]Sheet1!$A$3") を持たせ
といった一次元配列に納めるんですか?

すると、
"ABC41621"が何番目の要素になるかは、どうやって知るんですか?

喩えていえば、
今後、都道府県名は使わずに、0県,1県、2県とよぶことにする、
とルール化するようなものですな。現場は混乱するでしょう。

そのためには、別途
 "ABC41621" ---> 0
 "ABC41622" ---> 1
 "ABC41623" ---> 2
というような関係をどこかに持たせて、
ユーザー自身が逐一検索しなければなりません。
そうしたことを、Dictinaryは内部で効率的に行ってくれるのです。
(Hashテーブルという特別に工夫した仕組みを活用することで
 高速・効率的に行っているのが、Dictionaryというデータ構造なわけです。)

VBAの元になっているVB6という言語仕様には、Dictionaryを持っておらず、
外部のライブラリーに依存していますが、
気の利いたプログラム言語では、必ずといってよいほど言語仕様として
装備されている、とても一般的なデータ構造です。
(名称は色々で、Hashとか、DictionaryとかAssociated Arrayとか呼ばれます)

ですから、配列と同程度に普通に使えるものですし、
Dictinaryを使ったので重くなったということは無いはずです。


重くなってきたというのは、基本的にはデータ量が増えたことに起因しているのでしょう。
関係しなくなっている古いデータがあれば、それは別途のログに移すとか、
そうした方面の工夫の余地はありませんか?

【81395】Re:表の比較
お礼  T-K  - 20/7/15(水) 17:45 -

引用なし
パスワード
   回答ありがとうございます。
配列では厳しそうですね
データを整理してみます、

【81396】Re:表の比較
発言  マナ  - 20/7/15(水) 21:02 -

引用なし
パスワード
   ▼T-K さん:

無理矢理、配列を使ってみました。
たぶん、直接セルに数式を埋め込んで、
計算後に値に変換のほうがよいと思います。
色付けは、条件付き書式で対応してください。

Sub test()
  Dim tbl As Range
  Dim v
  Dim j As Long, k As Long
  Dim mX, mY

  Set tbl = Sheets("Sheet1").Range("A1").CurrentRegion
  
  With Sheets("Sheet2").Range("A1").CurrentRegion
    v = .Value
    For j = 2 To UBound(v, 1)
      For k = 3 To UBound(v, 2)
        mX = Application.Match(CLng(DateValue(v(1, k))), tbl.Rows(1), 0)
        mY = Application.Match(v(j, 1), tbl.Columns(1), 0)
        If IsNumeric(mX) * IsNumeric(mY) Then
          v(j, k) = Application.Index(tbl, mY, mX)
        End If
      Next
    Next
    .Value = v
  End With
 
End Sub

【81397】Re:表の比較
発言  マナ  - 20/7/15(水) 21:04 -

引用なし
パスワード
   ▼T-K さん:

dictionaryについて質問してもよいですか。
なぜ、配列を登録しているのでしょう。
アドレスだけではだめなのでしょうか。

>fDic(com & dt) = VBA.Array(c.Value, c.Address(External:=True))

【81398】Re:表の比較
発言  マナ  - 20/7/15(水) 21:40 -

引用なし
パスワード
   ▼T-K さん:

処理速度には、期待しないでください。
あくまで、配列の勉強が目的です。

>一番の理由は、配列を理解するため。

【81399】Re:表の比較
発言  T-K  - 20/7/15(水) 23:57 -

引用なし
パスワード
   配列を表に入れるこのプログラムは、教えていただいた
ものです。私が作成したものではありません。

出力用に既定の表があり、その表の行(商品データ)と列(日付)の&値をDictinaryのKeyとして
行と列の交差している値(注文数)とその値の入力されているアドレスをItemとして
Dictionaryに登録しているようです。
Hashテーブルという既定の機能を利用しているようですが、
アドレスを利用してどのようにコンピュータがそれを解釈しているかは
いまだにイメージできていません。そのようなものとおもっていまもつかっっています。
配列にはそのような機能はないようです。
プログラムを作成していただいて感謝しますが、
処理速度が遅いようであれば、現状と変わらないため参考までとさせていただきます。Matchで照合しているようですが、少しむずかしいです。
とりあえず調べてみます。

【81400】Re:表の比較
発言  マナ  - 20/7/16(木) 21:05 -

引用なし
パスワード
   ▼T-K さん:

>配列を表に入れるこのプログラムは、教えていただいた
>ものです。私が作成したものではありません。

それは、承知しています。
dictionaryで何をしているか理解できてなさそうだったので
根のため確認しました。

>処理速度が遅いようであれば、現状と変わらないため参考までとさせていただきます。Matchで照合しているようですが、少しむずかしいです。
>とりあえず調べてみます。

処理速度は考えていません。
あくまで配列の勉強です。
↓こういうことでしたので。

>一番の理由は、配列を理解するため。

速度重視なら、dictionaryの使い方を変更し
配列から、一括で、sheet2に書き込むようにすると
少しは速くなるはずです。

ただし、トライするのは、もっと単純なケースでよいので
dictionaryと配列を使えるようになってからが良いと思います。

【81410】Re:表の比較
発言  T-K  - 20/7/23(木) 23:51 -

引用なし
パスワード
   とりあえず、すべて人任せのところがある為
わからないなりに自分で考えて作ってみました。(下記に載せました)
支離滅裂な感じですが、一応動きました。
データが増えた場合この処理ではどうなのかわからないですが・・・
最後にデータをエクセルシートに処理する際に
繰り返し処理にて展開してますが一括での感じがわかりません
やはりDictinaryのほうがシンプルに処理できそうなのでことらを
これからも使用します。今回はアドバイスいただきありがとうございました。


Sub 展開()


Dim myval0(), myval, myval1(), myval2(), myval3() 'データ入力用配列の宣言
Dim Myoutpt, Myoutpt1(), Myoutpt2(), Myoutpt0(), Myoutpt3() '出力用配列の宣言
Dim msg


Dim 品番1 As Range
Dim 品番2 As Range


'--------------------------------------------------------

Dim sh1 As Worksheet 'シート宣言

Dim sh As Worksheet

'-----------------------------------変数(Long型作成) 宣言


Dim a As Long
Dim b As Long
Dim d As Long
Dim h As Long
Dim i As Long
Dim j As Long
Dim k As Long
Dim l As Long
Dim m As Long
Dim n As Long


'---------------------------------------


Application.ScreenUpdating = False '画面停止処理


Set sh = Worksheets("データ取り込み") 'Sh=データ取り込みシート

Set sh1 = Worksheets("集計") ' Sh1=集計シート


'入力用配列の作成------------------------------------------------------------

myval = sh.Range("A1").CurrentRegion.Value 'データ取り込みシートのデータを配列に格納する
ReDim myval1(2 To UBound(myval, 1)) '配列要素数を設定する
For i = 2 To UBound(myval, 1)

myval1(i) = myval(i, 1) & myval(i, 2) '品番データを配列に格納する


Next

ReDim myval2(3 To (UBound(myval, 2) - 4)) '配列要素数を設定する


For n = 3 To (UBound(myval, 2) - 4) '納期データを配列に格納する
myval2(n) = myval(1, n)

Next


ReDim myval0(2 To UBound(myval, 1), 3 To (UBound(myval, 2) - 4)) '配列要素を設定

For a = 2 To UBound(myval, 1)
For b = 3 To UBound(myval, 2) - 4 '計画数をデータに確保する

myval0(a, b) = myval(a, b)

Next
Next

n = 2
d = 3
ReDim myval3(2 To UBound(myval1, 1), 3 To UBound(myval2, 1)) '配列要素数を設定する

For l = 2 To UBound(myval1, 1) 'すべての情報を配列に格納する
For m = 3 To UBound(myval2, 1)


myval3(l, m) = Split(myval1(l) & "_" & myval2(m) & "_" & myval0(n, d), "_") 'データを区切って連結させる


If d = UBound(myval0, 2) Then
n = n + 1
d = 3
If n = UBound(myval0, 1) Then

Exit For
End If


Else

d = d + 1

End If


Next
Next


'出力用配列作成--------------------------------------------


Myoutpt = sh1.Range("A1").CurrentRegion.Value 'データ取り込みシートのデータを配列に格納する
ReDim Myoutpt1(2 To UBound(Myoutpt, 1)) '配列要素数を設定する
For i = 2 To UBound(Myoutpt, 1)

Myoutpt1(i) = Myoutpt(i, 1) & Myoutpt(i, 2) '品番データを配列に格納する


Next

ReDim Myoutpt2(4 To (UBound(Myoutpt, 2))) '配列要素数を設定する


For n = 4 To (UBound(Myoutpt, 2)) '納期データを配列に格納する
Myoutpt2(n) = Myoutpt(1, n)

Next


ReDim Myoutpt0(2 To UBound(Myoutpt, 1), 4 To UBound(Myoutpt, 2)) '配列要素を設定

For a = 2 To UBound(Myoutpt, 1)
For b = 4 To UBound(Myoutpt, 2) '計画数をデータに確保する

Myoutpt0(a, b) = Myoutpt(a, b)

 Next
Next


ReDim Myoutpt3(2 To UBound(Myoutpt1, 1), 4 To UBound(Myoutpt2, 1)) '配列要素数を設定する

For l = 2 To UBound(Myoutpt1, 1) 'すべての情報を配列に格納する
For m = 4 To UBound(Myoutpt2, 1)


Myoutpt3(l, m) = Split(Myoutpt1(l) & "_" & Myoutpt2(m) & "_" & Myoutpt0(l, m), "_") 'データを区切って”_”で連結させる


   Next
Next


For j = LBound(Myoutpt3, 1) To UBound(Myoutpt3, 1)
  For i = LBound(Myoutpt3, 2) To UBound(Myoutpt3, 2)
   For k = LBound(myval3, 1) To UBound(myval3, 1)
    For l = LBound(myval3, 2) To UBound(myval3, 2)
    
    
    If j > UBound(myval3, 1) Then 'データ取り込みの品番に新規があり上限が増えた場合処理しない
    Exit For
    End If


  If Myoutpt3(j, i)(0) & Myoutpt3(j, i)(1) = myval3(k, l)(0) & myval3(k, l)(1) Then '品番&納期の照合をして同じ場合値を取得
  
  
        Myoutpt3(j, i)(2) = myval3(k, l)(2)
       
       
        Else
        Myoutpt3(j, i)(2) = Myoutpt3(j, i)(2) '集計でーたにすでに値があり、今回取り込み対象外の場合集計のセルデータを登録


   End If


         Next
  
       Next
           
     Next
   Next


'------------------------------------------------------- 集計シートに値を出力する


For i = 2 To UBound(Myoutpt3, 1)

   sh1.Cells(i, 3).Value = Myoutpt3(i, 4)(0)

Next

  For i = 4 To UBound(Myoutpt3, 2)
   sh1.Cells(1, i).Value2 = Myoutpt3(2, i)(1)

  Next


For m = LBound(Myoutpt3, 1) To UBound(Myoutpt3, 1)

   For n = LBound(Myoutpt3, 2) To UBound(Myoutpt3, 2)


         sh1.Cells(m, n) = Myoutpt3(m, n)(2)


   Next
Next

'----------------------------------------------------------------------集計シート品番とデータ取り込みシートのデータを照合して違う場合色で表示する


Set 品番1 = sh.Range("A1:A1000")
Set 品番2 = sh1.Range("A1:A1000")
'bも同じようにしてください。


'カウンタが1からセルの個数になるまで繰り返し処理
For i = 1 To 品番1.Cells.Count
 If 品番1.Cells(i).Value <> 品番2.Cells(i).Value Then


品番1.Cells(i).Interior.ColorIndex = 6

 End If
Next i 'この行に来たら「For 〜」の行に勝手に戻


'-----------------------------------------------------------------------


Application.ScreenUpdating = True '画面更新をOKにする


MsgBox "処理終了"


End Sub

【81412】Re:表の比較
発言  マナ  - 20/7/24(金) 11:03 -

引用なし
パスワード
   ▼T-K さん:

>最後にデータをエクセルシートに処理する際に
>繰り返し処理にて展開してますが一括での感じがわかりません

それだと、速度改善にならないと思います。
dictionaryでも、一括で書き込まないと同じです。

Sub test2()
  Dim fSh As Worksheet
  Dim tSh As Worksheet
  Dim dicX As Object
  Dim dicY As Object
  Dim tbl As Range
  Dim i As Long, k As Long
  Dim dt As Double
  Dim com As String
  Dim mX, mY
  Dim w
 
  Application.ScreenUpdating = False
 
  Set dicX = CreateObject("Scripting.Dictionary")
  Set dicY = CreateObject("Scripting.Dictionary")

  Set fSh = Sheets("Sheet1")
  Set tSh = Sheets("Sheet2")
 
  fSh.Cells.Interior.ColorIndex = xlNone
  
  Set tbl = tSh.Range("A1").CurrentRegion
  w = tbl.Value
 
  With fSh.Range("A1").CurrentRegion
    For i = 2 To .Rows.Count
      com = .Cells(i, "B").Value
      If Not dicY.exists(com) Then
        mY = Application.Match(com, tbl.Columns("B"), 0)
        If IsError(mY) Then
          .Rows(i).Interior.ColorIndex = 3
        End If
        dicY(com) = mY
      End If
      
      If IsNumeric(dicY(com)) Then
        For k = 3 To .Columns.Count
          dt = .Cells(1, k).Value2
          If Not dicX.exists(dt) Then
            mX = Application.Match(dt, tbl.Rows(1), 0)
            If IsError(mX) Then
              .Columns(k).Interior.ColorIndex = 3
            End If
            dicX(dt) = mX
          End If
            
          If IsNumeric(dicX(dt)) Then
            w(dicY(com), dicX(dt)) = .Cells(i, k).Value
          End If
        Next
      End If
    Next
  End With
  
  tbl.Value = w
 
  MsgBox "転記完了"
 
End Sub

【81415】Re:表の比較
発言  マナ  - 20/7/24(金) 11:51 -

引用なし
パスワード
   ▼T-K さん:

dicYは、使う必要ありませんでした。

【81429】Re:表の比較
発言  T-K  - 20/7/29(水) 23:31 -

引用なし
パスワード
   返信ありがとうございます
Dictionaryを使ってのコード提示ありがとうございます。
シートに一度に書き込んでいるのは、コードをみて何となく理解できるのですが、
自分で応用ができないのが現状です。
いままでなら、このコードを少し変更して利用していますが、
今回の目的は質問にかいたように配列を理解することと、配列でDictionaryと同じ 表現ができるのかが課題です。
あと自分で作った物も無駄にしたくないため、どこを直せばいいのかを知りたいです


配列でもテーブル範囲を指定すれば一括で記入は可能なようですが、
Splitで区切った物を配列に入れたため複雑な構造になっていてうまくいきません

作っても”型が合いません”&"インデックスが有効範囲にありません"とエラーがでてしまっています。
もしわかるようであればおしえてください
よろしくお願いします。

【81433】Re:表の比較
発言  マナ  - 20/7/30(木) 19:30 -

引用なし
パスワード
   ▼T-K さん:

>今回の目的は質問にかいたように配列を理解することと、

配列を使った一括書き込みを理解するには、
最初にも書きましたが、もっと単純な例がよいです。

www.vbalab.sakura.ne.jp/vbaqa/c-board.cgi?cmd=ntr;tree=81369;id=excel

例えば、↑これは理解できていますか。

【81434】Re:表の比較
発言  マナ  - 20/7/30(木) 20:20 -

引用なし
パスワード
   ▼T-K さん:

>Dictionaryを使ってのコード提示ありがとうございます。

どちらかというと配列のコードのつもりだったのですが…


Sub test3()
  Dim fSh As Worksheet
  Dim tSh As Worksheet
  Dim tbl As Range
  Dim i As Long, k As Long
  Dim dt As Double
  Dim com As String
  Dim mX, mY
  Dim w
  Dim flg As Boolean

  Set fSh = Sheets("Sheet1")
  Set tSh = Sheets("Sheet2")

  fSh.Cells.Interior.ColorIndex = xlNone
 
  Set tbl = tSh.Range("A1").CurrentRegion
  w = tbl.Value

  With fSh.Range("A1").CurrentRegion
    For i = 2 To .Rows.Count
      com = .Cells(i, "B").Value
      mY = Application.Match(com, tbl.Columns("B"), 0)
      If IsError(mY) Then
        .Rows(i).Interior.ColorIndex = 3
      Else
        For k = 3 To .Columns.Count
          dt = .Cells(1, k).Value2
          mX = Application.Match(dt, tbl.Rows(1), 0)
          If IsError(mX) Then
            If Not flg Then .Columns(k).Interior.ColorIndex = 3
          Else
            w(mY, mX) = .Cells(i, k).Value
          End If
        Next
        flg = True
      End If
    Next
  End With
 
  tbl.Value = w

End Sub

【81435】Re:表の比較
お礼  T&#8211;K  - 20/8/1(土) 12:29 -

引用なし
パスワード
   送信ありがとうごさいます、
このプラグラムの内容が最初理解できず、
試行錯誤していたため、返信送れました。 
申し訳ありません。
mach関数の処理自体照合処理をして
値を配列に格納していると思いこんでいました。
dictionaryの場合、このような表現も
できるのかなと思いましたが、


配列ではindex番号でしか表現する方法
を知らないためw(my.mx)が?となっていました。
マッチ関数の結果が位置を出すものと知ってからは
処理の意味がわかりました。勉強不足ということです。
とりあえす利用ささて頂き高速になりました
感謝いたします。

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