[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『複数条件のカウントを転帰 日付が変わると転帰場所も変わる』(まさこ)
ブックA.xlsmの1シート(シートは月の枚数分あります:2017年9月であれば30個のシート シートの名前は1-30の数字)
C2に2017年9月1日のように日付
C3に木のように曜日を入力しています
シートの名前は1です。
氏名の右となりのセルには あ〜こ までの10パターン程度の文字が入力されます。 以下の表では あ い の2パターンですが。
C F G H I J K L M N O P Q R S 1 2 9月1日 3 木 4 大阪太郎 あ 滋賀花子 あ 大阪太郎 あ 滋賀花子 あ 三重太郎 い 5 大阪太郎 あ 滋賀花子 あ 三重太郎 い 6 大阪太郎 あ 7 8 大阪太郎 あ
ブックAの2シート
C F G H I J K L M N O P Q R S 1 2 9月2日 3 金 4 滋賀花子 あ 5 大阪太郎 あ 大阪太郎 あ
ブックB.xlsmのあシート (あ〜こ まで10パターン程度のシートが同様のレイアウトであります。)
A B C D ・・・ X Y Z AA AB AC AD AE AF AG AH AI ・・・
1
2
3
4 9月1日 9月2日 9月3日
5 木 金 土
6 氏名 ・・・ ○▲× 合計
7 大阪太郎 4 1 0 ←表示させたい
8 滋賀花子 2 1 0 ←表示させたい
9 三重太郎 0 0 0 ←表示させたい
ブックB.xlsmのいシート
A B C D ・・・ X Y Z AA AB AC AD AE AF AG AH AI ・・・
1
2
3
4 9月1日 9月2日 9月3日
5 木 金 土
6 氏名 ・・・ ○▲× 合計
7 兵庫太郎 0 0 0 ←表示させたい
8 和歌山花子 0 0 0 ←表示させたい
9 三重太郎 1 0 1 ←表示させたい
ブックBの各シートのC7からC列に氏名が入力されていきます。
☆マクロで出来たらうれしいこと☆
1,ブックB.xlsmのあシートのC7の名前と完全一致する文字列の右隣のセルがあ をブックA.xlsmのF4:K8の範囲でカウントし、ブックBのあシートのX7に表示。
同上 C8 同上 X8 。
同上 C9 同上 X9 。
2,ブックB.xlsmのあシートのC7の名前と完全一致する文字列の右隣のセルがあ をブックA.xlsmのL4:O8の範囲でカウントし、ブックBのあシートのY7に表示。
同上 C8 同上 Y8 。
同上 C9 同上 Y9 。
3,ブックB.xlsmのあシートのC7の名前と完全一致する文字列の右隣のセルがあ をブックA.xlsmのP4 : S8の範囲でカウントし、ブックBのあシートのZ7に表示。
同上 C8 同上 Z8 。
同上 C9 同上 Z9 。
4.ブックB.xlsmのいシートのC7の名前と完全一致する文字列の右隣のセルがい をブックA.xlsmのF4:K8の範囲でカウントし、ブックBのあシートのX7に表示。
同上 C8 同上 X8 。
同上 C9 同上 X9 。
5,ブックB.xlsmのいシートのC7の名前と完全一致する文字列の右隣のセルがい をブックA.xlsmのL4:O8の範囲でカウントし、ブックBのあシートのY7に表示。
同上 C8 同上 Y8 。
同上 C9 同上 Y9 。
6,ブックB.xlsmのいシートのC7の名前と完全一致する文字列の右隣のセルがい をブックA.xlsmのP4 : S8の範囲でカウントし、ブックBのあシートのZ7に表示。
同上 C8 同上 Z8 。
同上 C9 同上 Z9 。
以下同様に ブックBのう〜このシートで行う。
さらに、上記の行いたいことがマクロで可能であれば、
ブックAの2シートになると、X7に表示していたのがAB7に表示したい。同様にY7→AC7 、Z7→AD7 となります。
ブックAの3シートになると、AF7 、AG7、AH7と変わっていきます。
やはり、マクロを手動で書き換えるしか方法がないのでしょうか?
やはり説明が苦手です。
< 使用 Excel:Excel2010、使用 OS:WindowsXP >
文章読むの苦手で、解読に時間掛かりましたがこういうことでいいですか? ブックA、ブックBともに開いている状態です。 Option Explicit
Sub test() '//[必須]ツール>参照設定>Microsoft ScriptingRuntime Dim dic(2) As Dictionary Set dic(0) = New Dictionary Set dic(1) = New Dictionary Set dic(2) = New Dictionary
Dim rng(2) As String rng(0) = "F4:K8" rng(1) = "L4:O8" rng(2) = "P4:S8"
'//日付単位で出力しよう Dim shA As Worksheet Dim tbl As Variant Dim i As Long, r As Long, c As Long Dim id As String, cd As String Dim dt As Double Dim k As Variant For Each shA In Workbooks("A.xlsm").Sheets '★ dic(0).RemoveAll dic(1).RemoveAll dic(2).RemoveAll For i = 0 To 2 tbl = shA.Range(rng(i)).Value For r = 1 To UBound(tbl, 1) For c = 1 To UBound(tbl, 2) Step 2 id = tbl(r, c) '//名前 cd = tbl(r, c + 1) '//コード If id <> "" And cd <> "" Then If Not dic(i).Exists(cd) Then Set dic(i)(cd) = New Dictionary dic(i)(cd)(id) = dic(i)(cd)(id) + 1 End If Next c Next r Next i
dt = shA.Range("C2").Value With Workbooks("B.xlsm") '★ For i = 0 To 2 For Each k In dic(i).Keys With .Sheets(k) .Activate c = Application.WorksheetFunction.Match(dt, .Rows(4), 0) '日付で4行目を検索 For r = 7 To .Cells(Rows.Count, "C").End(xlUp).Row '7行目から最後の行まで id = Cells(r, "C").Value If dic(i)(k).Exists(id) Then Cells(r, c + i).Value = dic(i)(k)(id) End If Next r End With Next k Next i End With Next shA Set dic(0) = Nothing Set dic(1) = Nothing Set dic(2) = Nothing End Sub (稲葉) 2017/08/05(土) 15:39
ブックAのシート1から、ブックBの各シートに転帰だけでなく、ブックC、ブックDにも同様の条件があれば転帰させたいのですが、そのときはどう記載すればよろしいのでしょうか?シートの数は変動します。
(まさこ) 2017/08/05(土) 21:09
ブックAの内容をC Dのブックにも、ということですか? そうなるとループがひとつ増えますねえ あと、ミスが一ヵ所あったので再掲します 少しお待ちください (稲葉) 2017/08/06(日) 05:49
書いていて思ったのですが、同じ内容ならBブックをコピーでもよいような? あと注意事項書き忘れていましたが、 Aブックに名前があって、Bブックに名前が無い場合は、Bブックに出力されていません。 同様に、Aブックにコードがあって、Bブックのシートにコードが無い場合も出力されません。というかエラーになります。
Option Explicit Sub test() '2017/8/7 13:35 編集にて差し替えました '//[必須]ツール>参照設定>Microsoft ScriptingRuntime Dim WBa As Workbook Set WBa = Workbooks("A.xlsm")
Dim WBb(2) As Workbook Set WBb(0) = Workbooks("B.xlsm") Set WBb(1) = Workbooks("C.xlsm") Set WBb(2) = Workbooks("D.xlsm") 'ここまででエラーが出たら、ブックが開かれていない。
Dim dic(2) As Dictionary Set dic(0) = New Dictionary Set dic(1) = New Dictionary Set dic(2) = New Dictionary Dim rng(2) As String rng(0) = "F4:K8" rng(1) = "L4:O8" rng(2) = "P4:S8" '//日付単位で出力しよう Dim shA As Worksheet Dim tbl As Variant Dim i As Long, r As Long, c As Long Dim id As String, cd As String Dim dt As Double Dim wb As Long Dim k As Variant Dim shB As Worksheet Dim ErrNum As Long
For Each shA In WBa.Sheets If shA.Range("C2").Value = "" Then '日付セルが空白なので、何もしない Else '日付セルが空白以外なので、処理を継続 dic(0).RemoveAll dic(1).RemoveAll dic(2).RemoveAll For i = 0 To 2 tbl = shA.Range(rng(i)).Value For r = 1 To UBound(tbl, 1) For c = 1 To UBound(tbl, 2) Step 2 id = tbl(r, c) '//名前 cd = tbl(r, c + 1) '//コード If id <> "" And cd <> "" Then If Not dic(i).Exists(cd) Then Set dic(i)(cd) = New Dictionary dic(i)(cd)(id) = dic(i)(cd)(id) + 1 End If Next c Next r Next i dt = shA.Range("C2").Value For wb = 0 To UBound(WBb) For i = 0 To 2 For Each k In dic(i).Keys Set shB = Nothing ErrNum = 0 On Error Resume Next Set shB = WBb(wb).Sheets(k) ErrNum = Err.Number On Error GoTo 0 If ErrNum > 0 Then 'シートがないので何もしない Else 'シートがあるので集計を入力する c = Application.WorksheetFunction.Match(dt, shB.Rows(4), 0) '日付で4行目を検索 For r = 7 To shB.Cells(Rows.Count, "C").End(xlUp).Row '7行目から最後の行まで id = shB.Cells(r, "C").Value If dic(i)(k).Exists(id) Then shB.Cells(r, c + i).Value = dic(i)(k)(id) End If Next r End If Next k Next i Next wb End If Next shA Set dic(0) = Nothing Set dic(1) = Nothing Set dic(2) = Nothing End Sub
(稲葉) 2017/08/06(日) 06:33
(まさこ) 2017/08/06(日) 07:43
えーと、解決でよろしいですか? やってることは、ブックAにあるものをBCDに集計させていますので ブックAにて探す、という表現はちょっと語弊があります
また、全く同じ内容がないということは、ブックAにあって、BCDにない コード(シート)があると思うのですが、問題なく動いていますか? (稲葉) 2017/08/06(日) 08:50
ブックAにあるものを集計>表現の語弊すみません。
With WBb(wb).Sheets(k) にてインデックスが有効範囲にありませんとエラーがでてしまいます。
ここでエラーがでたらシートがないということでしたが、
ブックAにあって(氏名と右隣のコード)、BCDのどれかブックに氏名がある、かつ、シートがコードの名前になっているのですが。
ブックBCDは、それぞれシートの数もバラバラです。ブック間ではシート名前は重複している物もあれば、重複していないものもあります。しかし、ブックAにある氏名と右隣コードは、必ずBCDの、どれかにはC7以降に氏名が、シートの名前がコードの物が存在しています。
(まさこ) 2017/08/07(月) 00:11
最後に私のこのマクロの認識が合っていれば、一点だけ修正をお願いした後に、一旦解決とさせて頂きたいです。
・例えば、ブックAに氏名があり、その右隣のセルが あ とします。
ブックBのシートあ でブックAの氏名があった場合、出力されました。しかし、ブックBのシートい に氏名があるにも関わらず、シートあ が存在する為に、エラーは回避されてしまいました。この場合にエラーコードを出したいです。
そして、もしも最後にわがままを聞いて下さるならば、以下のことを実現させたいです。
ブックAに入力する名前が、ブックBCDのC7以降のどのシートにもなかった場合(完全一致しなかった場合)、入力エラーのメッセージを出したい(私にはチェンジイベントしか思いつかないですが)
または
ブックAの入力がすべて終わった時に、マクロを実行すると仮定。
BCDの各シートのC7以降の氏名と完全一致しない氏名が、ブックAのアクティブのシートに入力されていれば、ブックAの氏名が入力されているセルの背景色を赤色に塗りつぶしたい。
(まさこ) 2017/08/07(月) 03:17
◆処理の流れ ブックA 9/1シートを開く F4:K8の範囲でループし、下記のような入れ物を作る F4:K8 ├あ │├大阪太郎─3 │└滋賀花子─1 └い ├大阪太郎─1 └三重太郎─1 ブックBを開く 「あ」シートを開く ←このシート名は2つめの入れ物、ループする。(あ→い) C7から最終行まで見て、入れ物の名前と一致したら、カウントした数値を入れる ブックCを開く 「あ」シートを開く ←このシート名は2つめの入れ物、ループする。(あ→い) C7から最終行まで見て、入れ物の名前と一致したら、カウントした数値を入れる ブックDを開く 「あ」シートを開く ←このシート名は2つめの入れ物、ループする。(あ→い) C7から最終行まで見て、入れ物の名前と一致したら、カウントした数値を入れる ブックA 9/2シートを開く 以下繰り返し
>ブックBのシートあ でブックAの氏名があった場合、出力されました。 >しかし、ブックBのシートい に氏名があるにも関わらず、シートあ が存在する為に、エラーは回避されてしまいました。 上記処理の流れから、ありえません。 シートが存在しなければ、飛ばす処理は可能です。
>(略)エラーのメッセージを出したい >(略)セルの背景色を赤色に塗りつぶしたい。 少なくとも、私には無理です。 入力のたびに3つのブックのすべてのシートをループさせるなんて現実的ではないと思います。 提案ですが、入力開始前にブックAに氏名チェック用シートを作成し、条件付書式で対応が望ましいと思います。 (稲葉) 2017/08/07(月) 10:46
完了した手作業の変更を上書きされないために、
・ブックAのそれぞれのシートを開いた時に、C2に日付が空白の場合は処理を飛ばす。ということも是非とも教えて頂きたいです。
そして
・ブックBCDにシートが存在しなければ、飛ばす処理は可能ということですが、是非とも教えて頂きたいです。
実は、処理内容は膨大な量があり、数十人がブックABCDに入力していて、それを毎日チェックして、処理するという流れが大まかな実務の流れですので、大幅な時間の短縮になりそうです。感謝してもしきれないくらいです。なんとお礼を言っていいのやら。
>(略)エラーのメッセージを出したい >(略)セルの背景色を赤色に塗りつぶしたい。 ご提案ありがとうございます。条件付き書式で対応することにします。
(まさこ) 2017/08/07(月) 12:00
>完了した手作業の変更を上書きされないために (稲葉) 2017/08/06(日) 06:33 の投稿を差し替えましたので、ご確認ください。
>ご提案ありがとうございます。条件付き書式で対応することにします。 とのことでしたので、BCDブックにある氏名を書き出すコードです。 Aブックに新しいシートを作って、シートモジュールに入れてください。 Option Explicit
Sub 氏名一覧作成() '//[必須]ツール>参照設定>Microsoft ScriptingRuntime '//[必須]ブックAの氏名一覧を書き出したいシートモジュールに貼り付ける Me.Activate 'シートモジュール以外だとエラーになる
Dim WBb(2) As Workbook Set WBb(0) = Workbooks("B.xlsm") Set WBb(1) = Workbooks("C.xlsm") Set WBb(2) = Workbooks("D.xlsm") 'ブックを開いていないとエラーになる
Dim dic As Dictionary Set dic = New Dictionary
Dim i As Long Dim sh As Worksheet Dim r As Long For i = 0 To UBound(WBb, 1) For Each sh In WBb(i).Sheets For r = 7 To sh.Cells(Rows.Count, "C").End(xlUp).Row '7行目から最後の行まで dic(sh.Cells(r, "C").Value) = "" Next r Next sh Next i Me.Cells.ClearContents Me.Range("A1").Resize(dic.Count).Value = Application.Transpose(dic.Keys) Set dic = Nothing End Sub (稲葉) 2017/08/07(月) 13:38
弊社は月月火水木金金なので、残念ですがお会いできそうにないですね。ごめんなさいね。(冗談です) お礼一言あれば、満足です。
お仕事がんばってください。 (稲葉) 2017/08/07(月) 16:15
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.