質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

解決済

3回答

914閲覧

VBA マクロを使ってシート間で条件付きの転記をしていきたい

icecleam

総合スコア46

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

1グッド

0クリップ

投稿2020/10/01 13:48

編集2020/10/02 11:45

エクセルのシート間の値の加算処理、スキップ処理を含めた転記処理についてです。
以下、画像のようにMacのエクセルで転記を実装したいです。
大学の課題で、以下を出されています。

転記の際の加算の方法、同列に同じ文字列が含まれるさいには処理を実行しないことなど、インターネットで調査をしたのですが、なかなかうまく書けませんでした。。

何卒、よろしくお願いします。

実現したいこと

このような手順で処理を行っていこうと考えています。
結果的に[転記先]のように転記したい。

担当者名を上から順番に「転記元」から転記していく、そのとき「担当者」というセルがある場合、担当者名が同列で重複する場合の2通りで処理をスキップします。

転記元シートで各担当者の右に入力されている数値をそのまま年月日に対応して転記していく。
K3のように、同じ担当者で「年月日」が重なっているときは重なった数値同士を加算する。

[質問1シート]1行目 セルに値がない
→無処理

[質問1シート]2行目 C列の値が「担当者」
→スキップ

[質問1シート]3行目 C列の値が「担当者名」
→[質問2シート]のC3に転記

[質問1シート] 21行目 C列の「担当者名」が3行目と重複
→担当者名は重複しているので無処理、「年月日」と数値部分は担当者Aに追記、この時数値が重なった場合は加算する

以降繰り返し

転記元
イメージ説明

転記先
イメージ説明

困っている事

下記のソースコード記載の①、②部分が特にわからずに困っています。
①同列に同じ担当者が含まれる際の条件の設定方法
②数値を転記していく際に重複している値同士をを加算する

他の部分でも、修正するべき箇所等ございましたら、修正してくださって構いませんので、サンプル等をいただけないでしょうか。

長くなってしまいましたが、何卒よろしくお願いいたします。

現在まで完成しているコード

VBA

1Sub SheetTenki2() 2Dim ec As Long '年月の一番左から一番右までを取得 3Dim lngFromRowsNo As Long ' 検索する行位置 4Dim lngToRowsNo As Long ' 書きこむ行位置 5Dim lngFromColumnNo As Long ' 検索する列位置 6Dim lngToColumnNo As Long ' 書きこむ列位置 7Dim wsFrom As Worksheet ' 取得側Excelシート 8Dim wsTo As Worksheet ' 設定側Excelシート 9Dim ec1 As Long ' 担当者列の一番下の担当者のセルを取得 10Dim ec2 As Long ' 各担当者の一番右の数値のセルを取得 11 12'シート"質問1"を選択 13 Sheets("質問1").Select 14 15 lngFromRowsNo = 2 16 17 ec1 = wsFrom.Cells(lngFromRowsNo, 3).End(xlDown).Row 18 For lngFromRowsNo = 2 To .ec1 19 20 ' 「担当者」以外の文字列が含まれるセルの値をC3から下に転記していく 21 ' 転記していくとき、同じ担当者が含まれるときはスキップする(同じ担当者が記載されないようにする) ① 22 If Not (Left(wsFrom.Cells(lngFromRowsNo, 3).Value, 3) = "担当者" Or '転記する列に同じ担当者が含まれるときという処理 ) Then 23 24 GoTo NEXT99 25 26 End If 27 28 '担当者列に担当者を転記 29 wsTo.Cells(ToRowNo, 3).Value = wsFrom.Cells(lngFromRowsNo, 3).Value 30 31 '各担当者の右の数値を順に転記していく, −1としているのは一番右は「見込み合計」が入るから 32 ec2 = wsTo.Cells(ToRowNo, 4).End(xlToRight).Column - 1 33 lngToColumnNo = 4 34 35 36 ' 転記元のD列から数値が存在するセルまで検索 37 For lngFromColumnNo = 4 To .ec2 38 39 ' 取得した数値を転記していく 40 '数値を 転記していくときにセルが重複したら、その重複した数値同士を加算する② 41 wsTo.Cells(ToRowNo, lngToColumnNo).Value = wsFrom.Cells(lngFromRowsNo, lngFromColumnNo).Value 42 43 Next lngFromColumnNo 44 45 ' 1行下へ(転記先) 46ToRowNo = ToRowNo + 1 47 48NEXT99: 49 50 Next lngFromRowsNo 51 52End Sub

回答者様への追記
イメージ説明

ichijava👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meg_

2020/10/01 14:06

> ①同列に同じ担当者が含まれる際の条件の設定方法 配列を用意して、同じ担当者名がその配列内になければ追加する(=新規担当者と判断)、とかどうでしょうか?
icecleam

2020/10/01 14:09

ご質問ありがとうございます。 確かにその方がスマートですね。 その方法で実装できるのであれば、教えていただきたいです。 何卒よろしくお願いします
meg_

2020/10/01 14:10

あれ? > [質問1シート] 21行目 C列の「担当者名」が3行目と重複→スキップ と > K3のように、同じ担当者で「年月日」が重なっているときは重なった数値同士を加算する。 > ②数値を転記していく際に重複している値同士をを加算する とは矛盾していませんか? いづれにしても、 > ②数値を転記していく際に重複している値同士をを加算する に関しては、質問のコードが書けるのであれば問題なく書けるかと思いますが。
meg_

2020/10/01 14:17

> その方法で実装できるのであれば、教えていただきたいです。 配列の使い方が分からない、ということですか? 動的配列なら下記など分かりやすいかと思います。 http://officetanaka.net/excel/vba/variable/08.htm
icecleam

2020/10/01 14:19

担当者はC列には重複した状態にはならずに、必ず一人という状況を作りたいです。 3行目でAはすでに転記できているので、21行目では2020/10/1以降の数値のみの転記となります。 Aの2020/10/1は3行目でも転記元のK3で記載されており、21行目ではD21で記載されているので、そういった場合にその値同士を加算したいという意味でした。 伝わりづらくてすみません。 内容をご理解いただけたでしょうか
icecleam

2020/10/01 14:54 編集

> K3のように、同じ担当者で「年月日」が重なっているときは重なった数値同士を加算する。 →同じ担当者で「年月日」が重なっているときは重なった担当者の「年月日」の数値同士を加算する。 ということですね。 質問内容も編集しました。 >いづれにしても、 >> ②数値を転記していく際に重複している値同士をを加算する >に関しては、質問のコードが書けるのであれば問題なく書けるかと思いますが。 すみません、上記のコードは自分で書いたのですが「重複している値同士をを加算する」部分の処理がわかりませんでした。。
meg_

2020/10/01 14:58

では、下記の仕様提示が間違っていますね。”スキップ”だと何もしないことを意味しますので。 > > [質問1シート] 21行目 C列の「担当者名」が3行目と重複→スキップ 転記先のC列に同名の担当者が存在していれば、その人の該当する月に値を足していきたいわけですね。
icecleam

2020/10/01 14:59

はい!その通りです! 失礼しました、修正しておきます。
meg_

2020/10/01 15:03

> ①同列に同じ担当者が含まれる際の条件の設定方法 こちらについては、あるセル範囲にある値が存在するかどうかを調べる方法が分からない、ということでしょうか? 検索すれば情報は沢山ありますので調べましょう。
icecleam

2020/10/01 15:07

そちらについては、長時間調べて色々試したのですが今回の場合に当てはまるようにソースを書くことができませんでしたので、こちらでご質問させていただきました。。 重なった値を加算する方も同様です。
meg_

2020/10/01 15:12

もしかしたら、質問者さんは検索するのが苦手なのでしょうか? 「vba セル範囲 検索」で検索すると情報が見つかります。下記など良いかと思います。 http://officetanaka.net/excel/vba/tips/tips127.htm
icecleam

2020/10/01 15:21 編集

上記のリンクは両者とも見覚えがあります。 すみません、おそらくマクロはもちろんPG自体、初心者なため応用することに慣れていないのだと思います。。 調査を自分なりに進めた上での上記のコードになります。。
kitasue

2020/10/01 20:09

icecleamさんは、ichijavaさんと同一人物なのでしょうか。 それとも、同じプロジェクトのメンバーですか? あるいは、質問内容は何かの課題なのでしょうか。 以下と質問内容が同じです。 https://teratail.com/questions/295138 そこの私の回答も参考になさってください。
icecleam

2020/10/01 21:50 編集

すみません そちらのリンクの方とは同一人物ではありません。 同じ課題に取り組んでいる方だと思われます。。 リンク先のkitasueさんのご回答なさっている内容を参照させて頂きました。 参考にさせていただいて、現在のコードの修正を試みたのですが(せっかくここまで書いたのなら自分のコードで目的を達成したいという私のわがままです、すみません) 参照設定がMacのエクセルであるためか、回答通りの設定が出来ずにうまく実行することができませんでした… もし、ご迷惑でなければ上記の質問のコードを修正するような感じでご回答をいただければ幸いです。。 この業界の勉強を始めて日が浅いもので、知識が足りず的外れなことを書いているかもしれませんが、なにかあればおっしゃっていただけたらと思います。。 長文失礼いたしました。
kitasue

2020/10/01 22:55

作成されたコードはMacで動かすのでしょうか。それともWindowsで動かすのでしょうか。
icecleam

2020/10/01 23:01

Macで動かします。 記載するべきでしたね、すみません
meg_

2020/10/02 00:06

> Macで動かします。 記載するべきでしたね、すみません  ⇒ 質問に追記してください。 > 上記のリンクは両者とも見覚えがあります。  ⇒ 「試したこと」の欄に調べたこと・参考にしたけどここが分からなかったこととして書いておいてください。回答者の時間の無駄になってしまいます。 > 同じ課題に取り組んでいる方だと思われます。。  ⇒ 「課題」とは学校の課題ですか? そのあたりも質問に追記するべきでしょう。kitasueさんのように「icecleamさんは、ichijavaさんと同一人物なのでしょうか。」思われると回答は付かないと思います。 私が紹介したリンクはかなり分かりやすい説明だと思いますが、Macだから動かなかったのでしょうか? そこまでWindowsとMacでExcelVBAの動作って違いますか?
tatsu99

2020/10/02 01:42 編集

日付に関しての質問です。 1.yyyy/mm/ddのddの部分は1固定という前提で良いのでしょうか。(2020/1/2等はありえない) 2.転記元の日付は必ず転記先にも存在するという前提でよいのですか。 3.転記先の日付は、必ず、1月分ずつ日付が増えているという前提で良いですか。(月がとぶことはない) 4.質問1のシートの日付の列はD~L列固定で良いですか。(可変ではない)
icecleam

2020/10/02 03:47

tatsu99さんへ ご質問にお答えします 1.ddの部分は変わる可能性は考慮しなくて大丈夫です。 2.最大と最小で、値をとって1ヶ月毎に記載していくので、存在しない場合もあります。 3.月は飛ぶことはないので、その認識で問題ありません。 4.日付が存在する列までを考慮したいので、可変であるという認識でお願いします。
icecleam

2020/10/02 03:54 編集

megさんへ 質問内容の見直しと修正を実施しました。 Macであることは関係ないかもしれませんが、初心者なりにひとつの可能性として考えたものでした。 すみません、的外れな発言であったかもしれません。
kitasue

2020/10/02 04:34

「見込み合計」の列は、[質問1]シートのすべての行で同じ列ですか?(サンプルではM列)
kitasue

2020/10/02 06:35 編集

丸投げの質問ではないと思いますよ。分からない部分は、書きようがないじゃないですか。
icecleam

2020/10/02 11:17 編集

kitasueさんへ ご質問にお答えします。 いえ、[質問1]の見込み合計は年月日が下辺であるため、列が変化する可能性があります。 宜しくお願いします。 >丸投げの質問ではないと思いますよ。分からない部分は、書きようがないじ>ゃないですか。 フォローありがとうございます。。
guest

回答3

0

tatsu99さんのDictionay版の回答を参考に、DictionaryをCollectionに変更してみました。
申し訳ありませんが、Mac上での動作確認はしていません。

VBA

1Option Explicit 2 3Const cnsWsh1RowBgn = 2 4Const cnsWsh1Col担当者 = 3 'C列 5Const cnsWsh1Col年月日 = 4 'D列 6Const cnsWsh2Row年月日 = 2 7Const cnsWsh2RowBgn = 3 8Const cnsWsh2Col担当者 = 3 'C列 9Const cnsWsh2Col年月日 = 4 'D列 10 11Sub SheetTenki2() 12 Dim lngWsh1Row As Long 13 Dim lngWsh1RowEnd As Long 14 Dim strWsh1担当者 As String 15 Dim lngWsh1Col As Long 16 Dim lngWsh2Row As Long 17 Dim lngWsh2Col As Long 18 Dim wsh1 As Worksheet 19 Dim wsh2 As Worksheet 20 Dim clcWsh2Row担当者 As Collection 21 Dim var As Variant 22 Dim lngCount As Long 23 Dim varWsh1年月日 As Variant 24 Dim i As Long 25 26 Set wsh1 = Worksheets("質問1") 27 Set wsh2 = Worksheets("質問2") 28 Set clcWsh2Row担当者 = New Collection 29 30'設定先消去 31 32 wsh2.Range(wsh2.Cells(cnsWsh2RowBgn, cnsWsh2Col担当者), wsh2.Range("A1").SpecialCells(xlCellTypeLastCell)).ClearContents 33 34'wsh2の担当者の行番号をCollectionに設定 35 36 lngWsh1RowEnd = wsh1.Cells(wsh1.Rows.Count, cnsWsh1Col担当者).End(xlUp).Row 37 For lngWsh1Row = cnsWsh1RowBgn To lngWsh1RowEnd 38 If IsDate(wsh1.Cells(lngWsh1Row, cnsWsh1Col年月日).Value) = False Then 39 strWsh1担当者 = wsh1.Cells(lngWsh1Row, cnsWsh1Col担当者).Value 40 lngCount = clcWsh2Row担当者.Count 41 lngWsh2Row = cnsWsh2RowBgn + lngCount 42 On Error Resume Next 43 clcWsh2Row担当者.Add Item:=lngWsh2Row, Key:=strWsh1担当者 44 On Error GoTo 0 45 If clcWsh2Row担当者.Count <> lngCount Then 46 wsh2.Cells(lngWsh2Row, cnsWsh2Col担当者).Value = strWsh1担当者 47 End If 48 End If 49 Next lngWsh1Row 50 51'値の加算 52 53 For lngWsh1Row = cnsWsh1RowBgn To lngWsh1RowEnd 54 Select Case True 55 Case IsDate(wsh1.Cells(lngWsh1Row, cnsWsh1Col年月日).Value) 56 varWsh1年月日 = wsh1.Range(wsh1.Cells(lngWsh1Row, cnsWsh1Col年月日), wsh1.Cells(lngWsh1Row, wsh1.Columns.Count).End(xlToLeft)).Value 57 Case Else 58 strWsh1担当者 = wsh1.Cells(lngWsh1Row, cnsWsh1Col担当者).Value 59 lngWsh2Row = clcWsh2Row担当者(strWsh1担当者) 60 For i = LBound(varWsh1年月日, 2) To UBound(varWsh1年月日, 2) 61 If IsDate(varWsh1年月日(1, i)) Then 62 lngWsh2Col = DateDiff("m", wsh2.Cells(cnsWsh2Row年月日, cnsWsh2Col年月日).Value, varWsh1年月日(1, i)) + cnsWsh2Col年月日 63 var = wsh1.Cells(lngWsh1Row, cnsWsh1Col年月日 + i - 1).Value 64 Select Case True 65 Case var = "" 66 Case IsNumeric(var) 67 wsh2.Cells(lngWsh2Row, lngWsh2Col).Value = wsh2.Cells(lngWsh2Row, lngWsh2Col).Value + var 68 End Select 69 End If 70 Next i 71 End Select 72 Next lngWsh1Row 73 74 Set clcWsh2Row担当者 = Nothing 75 Set wsh2 = Nothing 76 Set wsh1 = Nothing 77 78End Sub

投稿2020/10/03 10:16

kitasue

総合スコア314

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

"Scripting.Dictionary"を使わないバージョンです。
あまりデータが多いと遅くなるかも知れません。

VBA

1Option Explicit 2'Scripting.Dictionaryを使わないバージョン 3Dim sh1 As Worksheet '質問1シート 4Dim sh2 As Worksheet '質問2シート 5Dim tan_names() As String '担当者名を格納する文字列 6Dim tan_count As Long '担当者の数 7Dim start_date As Variant '質問2シートの開始日 8 9 10Public Sub 転記2() 11 Dim row1 As Long '質問1シートの行番号 12 Dim row2 As Long '質問2シートの行番号 13 Dim maxrow1 As Long '質問1シート最大行 14 Dim maxcol1 As Long '質問1シートの個々の担当者行の最大列 15 Dim val As String '処理中の値 16 Dim tan_row As Long '担当者の行番号 17 Call tan_init '担当者テーブルクリア 18 Set sh1 = Worksheets("質問1") 19 Set sh2 = Worksheets("質問2") 20 '質問2シートの3行目以降をクリア 21 sh2.Rows("3:" & Rows.Count).ClearContents 22 start_date = sh2.Range("D2").Value 23 maxrow1 = sh1.Cells(Rows.Count, "C").End(xlUp).Row '質問1シート C列 最終行を求める 24 '質問1シートを2行から最終行まで繰り返す 25 For row1 = 2 To maxrow1 26 val = sh1.Cells(row1, "C").Value 27 Select Case val 28 Case "" '無処理 29 Case "担当者" 30 maxcol1 = sh1.Cells(row1, Columns.Count).End(xlToLeft).Column 'この行の最終列を求める 31 tan_row = row1 'この行を記憶(担当者の行) 32 Case Else '上記以外(個々の担当者) 33 '担当者テーブルを検索し、その要素番号を取得する。先頭が1なので、+2すると質問2シートの行番号になる 34 row2 = tan_find(val) + 2 35 sh2.Cells(row2, "C").Value = val 36 Call atai_tenki(row1, row2, tan_row, maxcol1) '質問2シートへの転記 37 End Select 38 Next 39 MsgBox ("完了") 40End Sub 41 '個々の担当者の処理 42Private Sub atai_tenki(ByVal row1 As Long, ByVal row2 As Long, ByVal tan_row As Long, ByVal maxcol1 As Long) 43 Dim wcol2 As Long '質問2シートの加算先の列 44 Dim wdate As Variant '日付 45 Dim sabun As Long '月の差(質問2シートの開始月と処理月の差) 46 Dim wcol1 As Long '質問1シートの処理中の列 47 '当該行の4列から最終列の1つ前まで繰り返す 48 For wcol1 = 4 To maxcol1 - 1 49 'この列の日付を取得 50 wdate = sh1.Cells(tan_row, wcol1) 51 '取得した日付が質問2シートのどの位置にあるか算出する 52 sabun = DateDiff("m", start_date, wdate) 53 wcol2 = 4 + sabun 54 '数値が設定されているなら、質問2シートの該当月に加算する 55 If sh1.Cells(row1, wcol1).Value <> "" And IsNumeric(sh1.Cells(row1, wcol1).Value) = True Then 56 sh2.Cells(row2, wcol2).Value = sh2.Cells(row2, wcol2).Value + sh1.Cells(row1, wcol1).Value 57 End If 58 Next 59End Sub 60 61 62'担当者テーブル初期化 63Private Sub tan_init() 64 tan_count = 0 65 ReDim tan_nems(tan_count) 66End Sub 67 68'指定された名前で担当者テーブルを検索し、その要素の番号を返す(1以上の値) 69'存在しない場合は、テーブルに追加し、その要素の番号を返す 70Private Function tan_find(ByVal name As String) As Long 71 Dim i As Long 72 'tan_namesテーブルをnemeで検索 先頭(0)は使用しない 73 For i = 1 To tan_count 74 '存在すれば、その要素番号を返す 75 If tan_names(i) = name Then 76 tan_find = i 77 Exit Function 78 End If 79 Next 80 '存在しない場合、nameを追加する 81 tan_count = tan_count + 1 82 ReDim Preserve tan_names(tan_count) 83 tan_names(tan_count) = name 84 tan_find = tan_count 85End Function 86 87

投稿2020/10/02 13:01

tatsu99

総合スコア5493

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

icecleam

2020/10/02 13:26

ありがとうございます! 上記のコードで実装することができました!
icecleam

2020/10/03 19:55

すみません 補足でご質問したいことがあります。 以下の2行では具体的にどのような処理を行っているのでしょうか。 ご迷惑でなければ教えていただきたいです。。 ---- wcol2 = sabun + 4 ----- ----- tan_find = tan_count -----
tatsu99

2020/10/03 22:25

wcol2は質問2シートへ設定する列の番号です。 2020/3/1がD列なので番号は4になります。 2020/3/1なら4 2020/4/1なら5 2020/5/1なら6 のようになれば良いわけです。 もし、質問1シートの日付が2020/6/1なら、sabun(月の差)は3なので wcol2=3+4 となり結果は7になります。よって、G列が設定する列となります。 次に、tan_find = tan_countですが、 tan_find=XXXとすると、tan_findが呼び出し元へ返す値を設定します。 最初の1件目(担当者=A)は、tan_names内にないので、tan_count=1となり tan_find=tab_countが実行されるので、呼び出し元に1が返ります。 次の2件目(担当者=C)は、同様に呼び出し元に2が返ります。 質問1シートの21行の担当者=Aの場合は、既にtan_names内に存在するので、 tan_find = i Exit Function が、実行されます。この時iは1なので、呼び出し元に1が返ります。
icecleam

2020/10/05 10:51

ありがとうございます! 重ね重ね申し訳ないのですが、もう一つご質問があります。。 今回「Option Explicit」を使用したマクロになっていると思うのですが、「Option Explicit」を使わない形に修正したい時、全体はどのように修正すれば良いのでしょうか。 教えていただければ幸いです。。
tatsu99

2020/10/05 11:33

単純にOption Explicitを削除すれば良いだけです。 但し、個人的には、Option Explicitを使用することを推奨します。 想像ですが、私の提示したマクロとほかのマクロを1つのmoduleに格納しようとされていると理解しました。ほかのマクロがOption Explicitを使用していないので、変数が未定義のエラーがでているのだと思います。その場合、変数 xxxが未定義なら dim xxx と宣言すれば、エラーはなくなりますので、そのようにしてください。 本来なら dim xxx as Longとかdim xxx as Stringとか型を明確に指定する方が良いのですが、型が判らない場合は dim xxx でもエラーはとれますので、そのようにしてください。
icecleam

2020/10/05 11:46

ありがとうございます すみません、モジュールをまとめようとしているわけではなく、課題のルールとしてOption Explicitは使ってはいけなかったみたいで。。 今、Option Explicitを削除して正常に動くことは確認したのですが、以下の宣言部分は「Public Sub 転記2()」の上にそのまま存在する形で問題ないのでしょうか。 Option Explicitを消すだけという簡単な対応だけで済んでしまって、なんか不安になってしまいました。。 Dim sh1 As Worksheet '質問1シート Dim sh2 As Worksheet '質問2シート Dim tan_names() As String '担当者名を格納する文字列 Dim tan_count As Long '担当者の数 Dim start_date As Variant '質問2シートの開始日
tatsu99

2020/10/05 12:01

Option Explicitの意味は、変数を定義しないでいきなり使用した場合、それをエラーにするという機能です。 従って、Option Explicitが宣言されて正常に実行できるものは、当然、Option Explicitをなくしても正常に実行できます。 Dim sh1 As Worksheet '質問1シート(以降省略)の部分は、 各プロシージャ(Public Sub 転記2、Private Function tan_find等)の外側で宣言されています。 これは、どのプロシージャからも参照/更新が可能という意味です。 従って、Public Sub 転記2()の外側で定義します。(Public Sub 転記2()の中で定義するとPrivate Sub atai_tenkiから参照できなくなるのエラーになります)
icecleam

2020/10/05 12:18

Option Explicitとはそういう意味だったのですね それでは上記でご回答いただいた、コードのOption Explicit部分を消しただけのコードでも、正常なコードと言えるということですね。 ご回答いただきありがとうございます
guest

0

前提として質問1シートに記述されている日付は質問2シートの最小日付~最大日付の範囲内にあるという前提です。範囲内にないと、マクロが暴走します。例として2018/1/1がもし、質問1シートにあるとマクロが暴走します。
以下のマクロを標準モジュールに設定してください。
windowsでのみ確認しています。あなたの環境で正常に動作しない場合は、その旨補足してください。
その原因がmac由来なら、お手上げですが、excelのレイアウトの齟齬等であれば、解決可能かも知れません。
標準モジュールの図

VBA

1Option Explicit 2 3Dim sh1 As Worksheet '質問1シート 4Dim sh2 As Worksheet '質問2シート 5Dim dicT As Object '連想配列 キー:担当者名 値:質問2シートの行番号 6Dim start_date As Variant '質問2シートの開始日 7 8 9Public Sub 転記() 10 Dim row1 As Long 11 Dim maxrow1 As Long '質問1シート最大行 12 Dim maxrow2 As Long '質問2シート最大行 13 Dim maxcol1 As Long '質問1シートの個々の担当者行の最大列 14 Dim val As String '処理中の値 15 Dim tan_row As Long '担当者の行番号 16 Set dicT = CreateObject("Scripting.Dictionary") ' 連想配列の定義 17 Set sh1 = Worksheets("質問1") 18 Set sh2 = Worksheets("質問2") 19 '質問2シートの3行目以降をクリア 20 sh2.Rows("3:" & Rows.Count).ClearContents 21 start_date = sh2.Range("D2").Value 22 maxrow1 = sh1.Cells(Rows.Count, "C").End(xlUp).Row '質問1シート C列 最終行を求める 23 maxrow2 = 3 '質問2シートの担当者の開始行 24 '質問1シートを2行から最終行まで繰り返す 25 For row1 = 2 To maxrow1 26 val = sh1.Cells(row1, "C").Value 27 Select Case val 28 Case "" '無処理 29 Case "担当者" 30 maxcol1 = sh1.Cells(row1, Columns.Count).End(xlToLeft).Column 'この行の最終列を求める 31 tan_row = row1 'この行を記憶(担当者の行) 32 Case Else '上記以外(個々の担当者) 33 If dicT.Exists(val) = False Then 34 '最初の出現時、担当者に割り当てた質問2シートの行番号を記憶する 35 dicT(val) = maxrow2 36 sh2.Cells(maxrow2, "C").Value = val 37 maxrow2 = maxrow2 + 1 38 End If 39 Call atai_tenki(val, row1, tan_row, maxcol1) '質問2シートへの転記 40 End Select 41 Next 42 MsgBox ("完了") 43End Sub 44 '個々の担当者の処理 45Private Sub atai_tenki(ByVal tan_name As String, ByVal row1 As Long, ByVal tan_row As Long, ByVal maxcol1 As Long) 46 Dim wrow2 As Long '質問2シートの加算先の行 47 Dim wcol2 As Long '質問2シートの加算先の列 48 Dim wdate As Variant '日付 49 Dim sabun As Long '月の差(質問2シートの開始月と処理月の差) 50 Dim wcol1 As Long '質問1シートの処理中の列 51 wrow2 = dicT(tan_name) '担当者に割り当てられた質問2シートの行番号を取得 52 '当該行の4列から最終列の1つ前まで繰り返す 53 For wcol1 = 4 To maxcol1 - 1 54 'この列の日付を取得 55 wdate = sh1.Cells(tan_row, wcol1) 56 '取得した日付が質問2シートのどの位置にあるか算出する 57 sabun = DateDiff("m", start_date, wdate) 58 wcol2 = 4 + sabun 59 '数値が設定されているなら、質問2シートの該当月に加算する 60 If sh1.Cells(row1, wcol1).Value <> "" And IsNumeric(sh1.Cells(row1, wcol1).Value) = True Then 61 sh2.Cells(wrow2, wcol2).Value = sh2.Cells(wrow2, wcol2).Value + sh1.Cells(row1, wcol1).Value 62 End If 63 Next 64End Sub 65

投稿2020/10/02 06:12

編集2020/10/02 11:38
tatsu99

総合スコア5493

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

icecleam

2020/10/02 11:14 編集

ご回答いただきありがとうございます! 上記のコードを実行したら エラーメッセージ「ActiveXコンポーネントはオブジェクトを作成できません」と出てしまうのですが、どうすれば良いでしょうか。。 また、以下のマクロを標準モジュールに設定 というのは普通のマクロと同様に実行することと何か違いはあるのでしょうか 質問が多くてすみませんがお答えいただければと思います。。
tatsu99

2020/10/02 11:43

windowsのexcel2007ですが、標準モジュールの図を追加しました。macにこのような個所はないのでしょうか。 「ActiveXコンポーネントはオブジェクトを作成できません」は、マクロのどの行で発生しますか?
icecleam

2020/10/02 11:47

今、質問に画像を追加しましたのでご確認ください。 >「ActiveXコンポーネントはオブジェクトを作成できません」は、マクロの>どの行で発生しますか? デバッグをした際に、以下で止まっていました。 --- Set dicT = CreateObject("Scripting.Dictionary") ' 連想配列の定義 ---- すみませんが、ご確認いただければと思います。 宜しくお願いします
icecleam

2020/10/02 11:57

ですね、私も今ちょうど同じような内容の記事を見つけたところでした。。 せっかくご回答いただいたのに申し訳ありません。 引き続きご回答はいただけたりしますでしょうか。。
tatsu99

2020/10/02 12:15

もう少し、本当に使えないのか調べてみます。本当に使えない場合は、"Scripting.Dictionary"を使わない方法を検討してみます。
icecleam

2020/10/02 12:18

ありがとうございます。。 当然ではありますが、こちらでも調査を進め、回答が見つかり次第こちらでご連絡させていただきます。 補足 こちらでも調べた感じだと、"Scripting.Dictionary"はやはりMACでは使えない線が強そうです。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問