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

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

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

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

マクロ

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

Q&A

解決済

2回答

3444閲覧

VBA シート間の転記をする際に日付の最大値と最小値を求めて、1ヶ月ごとに転記していきたい。

icecleam

総合スコア46

VBA

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

マクロ

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

0グッド

1クリップ

投稿2020/09/27 17:17

編集2020/10/01 14:48

エクセルのシート間の値のコピー処理で
日付の最大値と最小値を取得して、最小値から最大値まで1ヶ月ごとに転記していきたいです。

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

実現したいこと

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

[質問1シート]1行目 D列の値がyyyy/mm/dd形式ではない
→無処理

[質問1シート]2行目 D列の値がyyyy/mm/dd形式である
→年月の値を取得し、取得した全ての日付の最小値と最大値を求める
...
以降、yyyy/mm/dd形式かそうでないかで処理の繰り返し

転記元
イメージ説明

転記先
イメージ説明

困っている事

上記「実現したいこと」記載の
「各行で年月の値を取得し、最小値と最大値を求める」処理の方法がわかりません。→解決済み

ご回答いただいた内容を参照して、ソースを作成し直したが(現在まで完成しているコード)
「オブジェクト変数またはWithブロック変数が設定されていません」
という内容のエラーメッセージが出てしまう。

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

VBA

1Sub SheetTenki() 2' 3 Dim ec As Long '年月の一番左から一番右までを取得 4 Dim lngFromRowsNo As Long ' 検索する行位置 5 Dim lngToRowsNo As Long ' 書きこむ行位置 6 Dim wsFrom As Worksheet ' 取得側Excelシート 7 Dim wsTo As Worksheet ' 設定側Excelシート 8 9 Dim datMax As Date '日付最大値 10 Dim datMin As Date '日付最小値 11 Dim enddatMax As Date ' 最終的な日付最大値 12 Dim enddatMin As Date '最終的な日付最小値 13 Dim ToColumnNo As Long 14 15 enddatMax = #1/1/100# '日付最大値に最小値を設定 16 enddatMin = #1/1/9999# '日付最最少値に最大値を設定 17 ToColumnNo = 4 18 19 20'シート"質問1"を選択 21 Set wsFrom = Worksheets("質問1") 22 23 'D列を上から検索していき、yyyy/mm/dd形式のセルを抽出する 24 For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count 25 If IsDate(wsFrom.Cells(lngFromRowsNo, 4).Value) Then 26 27 '抽出した行の年月を値が含まれる最大まで(右側)取得 28 '?1は見込み合計を含まないため 29 ec = wsFrom.Cells(lngFromRowsNo, 4).End(xlToRight).Column - 1 30 31 '取得した年月の最大値と最小値を求めて、最小値から最大値までを1ヶ月間隔で転記していく 32 With WorksheetFunction 33 datMax = .Max(Range(wsFrom.Cells(lngFromRowsNo, 4), wsFrom.Cells(lngFromRowsNo, ec))) 34 datMin = .Min(Range(wsFrom.Cells(lngFromRowsNo, 4), wsFrom.Cells(lngFromRowsNo, ec))) 35 End With 36 'どこに転記するか不明なのでとりあえずメッセージボックスに表示 37 'MsgBox "最大値:" & datMax & " 最小値:" & datMin 38 39 If enddatMin > datMin Then 40 enddatMin = datMin 41 End If 42 If enddatMax < datMax Then 43 enddatMax = datMax 44 End If 45 46 ' 次の行へ 47 lngToRowsNo = lngToRowsNo + 1 48 49 End If 50 51 Next lngFromRowsNo 52 53 Do 54 wsTo.Cells(2, ToColumnNo).Value = enddatMin 55 ToColumnNo = ToColumnNo + 1 '次の列へ 56 enddatMin = DateAdd("m", 1, enddatMin) '一ヶ月後 57 Loop Until enddatMin > enddatMax 58 59End Sub

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

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

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

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

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

kuma_kuma_

2020/09/27 22:51

>[質問1シート]1行目 D列の値がyyyy/mm/dd形式ではない >[質問1シート]2行目 D列の値がyyyy/mm/dd形式である 質問がおかしくありませんか? >[質問1シート]1行目 D列の値がyyyy/mm/dd形式ではない >[質問2シート]1行目 D列の値がyyyy/mm/dd形式である ならまだ意味が判りますが それとも転記元の写真誤り?
guest

回答2

0

ベストアンサー

日付がどうかの判断は IsDate関数でできます。

css

1If IsDate(.Cells(lngFromRowsNo, 4).Value) Then 2 '日付の時の処理 3End If

転記元の画像を見ると、担当者 の横から日付が並んでいるので、
"担当者"を FindメソッドかIndexで検索したほうが高速だとは思います。

最大値、最小値は、Max関数とMin関数で取得できます。

vba

1 Dim ec As Long '最終列 2 Dim datMax as Date '日付最大値 3 Dim datMin as Date '日付最小値 4 5 ec = wsTo.Cells(lngFromRowsNo, 4).End(xlToRight).Column - 1 6 With WorksheetFunction 7 datMax = .Max(Range(.Cells(lngFromRowsNo, 4), .Cells(lngFromRowsNo, ec))) 8 datMin = .Min(Range(.Cells(lngFromRowsNo, 4), .Cells(lngFromRowsNo, ec))) 9 End With

こちらで作成したサンプルでは下記で動いてます。

vba

1Sub SheetTenki() 2' 3 Dim ec As Long '年月の一番左から一番右までを取得 4 Dim lngFromRowsNo As Long ' 検索する行位置 5 Dim lngToRowsNo As Long ' 書きこむ行位置 6 Dim wsFrom As Worksheet ' 取得側Excelシート 7 Dim wsTo As Worksheet ' 設定側Excelシート 8 9 Dim datMax As Date '日付最大値 10 Dim datMin As Date '日付最小値 11 12'シート"質問1"を選択 13 Set wsFrom = Worksheets("質問1") 14 15 'D列を上から検索していき、yyyy/mm/dd形式のセルを抽出する 16 For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count 17 If IsDate(wsFrom.Cells(lngFromRowsNo, 4).Value) Then 18 19 '抽出した行の年月を値が含まれる最大まで(右側)取得 20 '?1は見込み合計を含まないため 21 ec = wsFrom.Cells(lngFromRowsNo, 4).End(xlToRight).Column - 1 22 23 '取得した年月の最大値と最小値を求めて、最小値から最大値までを1ヶ月間隔で転記していく 24 With WorksheetFunction 25 datMax = .Max(Range(wsFrom.Cells(lngFromRowsNo, 4), wsFrom.Cells(lngFromRowsNo, ec))) 26 datMin = .Min(Range(wsFrom.Cells(lngFromRowsNo, 4), wsFrom.Cells(lngFromRowsNo, ec))) 27 End With 28 'どこに転記するか不明なのでとりあえずメッセージボックスに表示 29 MsgBox "最大値:" & datMax & " 最小値:" & datMin 30 31 ' 次の行へ 32 lngToRowsNo = lngToRowsNo + 1 33 34 End If 35 Next lngFromRowsNo 36 37End Sub

投稿2020/09/28 03:44

編集2020/09/29 15:21
hatena19

総合スコア34075

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

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

icecleam

2020/09/28 04:25 編集

ご回答いただきありがとうございます。 ご回答者さまの回答を参考に以下のようにソースを修正したのですが、エラーメッセージ「メソッドまたはデータ メンバーが見つかりません。」が datMax = .Max(Range(.Cells(lngFromRowsNo, 4), .Cells(lngFromRowsNo, ec))) の.Cellのところで出てしまいました。 うまく実行するにはどのように修正すれば良いでしょうか。。 全体のソースコード ーーー Sub SheetTenki() ' Dim ec As Long '年月の一番左から一番右までを取得 Dim lngFromRowsNo As Long ' 検索する行位置 Dim lngToRowsNo As Long ' 書きこむ行位置 Dim wsFrom As Worksheet ' 取得側Excelシート Dim wsTo As Worksheet ' 設定側Excelシート Dim datMax As Date '日付最大値 Dim datMin As Date '日付最小値 'シート"質問1"を選択 Sheets("質問1").Select 'D列を上から検索していき、yyyy/mm/dd形式のセルを抽出する For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count If IsDate(wsFrom.Cells(lngFromRowsNo, 4).Value) Then '抽出した行の年月を値が含まれる最大まで(右側)取得 '−1は見込み合計を含まないため ec = wsFrom.Cells(lngFromRowsNo, 4).End(xlToRight).Column - 1 '取得した年月の最大値と最小値を求めて、最小値から最大値までを1ヶ月間隔で転記していく With WorksheetFunction datMax = .Max(Range(.Cells(lngFromRowsNo, 4), .Cells(lngFromRowsNo, ec))) datMin = .Min(Range(.Cells(lngFromRowsNo, 4), .Cells(lngFromRowsNo, ec))) End With ' 次の行へ lngToRowsNo = lngToRowsNo + 1 End If Next lngFromRowsNo End Sub
Usirow

2020/09/29 08:41 編集

もう自己解決されてるかもしれませんが、該当の箇所は WorksheetFunctionで括られているため、以下のように書かないとエラーになりますね。 With WorksheetFunction datMax = .Max(Range(Cells(lngFromRowsNo, 4), Cells(lngFromRowsNo, ec))) datMin = .Min(Range(Cells(lngFromRowsNo, 4), Cells(lngFromRowsNo, ec))) End With
icecleam

2020/09/29 11:58

Usirowさんへ 以下のように修正したのですが、「オブジェクト変数またはWithブロック変数が設定されていません」というエラーメッセージが出てまいました。。 もしよければ、正常に転記するためにはどのように修正すれば良いか、教えていただけないでしょうか。。 Sub SheetTenki() ' Dim ec As Long '年月の一番左から一番右までを取得 Dim lngFromRowsNo As Long ' 検索する行位置 Dim lngToRowsNo As Long ' 書きこむ行位置 Dim wsFrom As Worksheet ' 取得側Excelシート Dim wsTo As Worksheet ' 設定側Excelシート Dim datMax As Date '日付最大値 Dim datMin As Date '日付最小値 'シート"質問1"を選択 Sheets("質問1").Select 'D列を上から検索していき、yyyy/mm/dd形式のセルを抽出する For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count If IsDate(wsFrom.Cells(lngFromRowsNo, 4).Value) Then '抽出した行の年月を値が含まれる最大まで(右側)取得 '−1は見込み合計を含まないため ec = wsFrom.Cells(lngFromRowsNo, 4).End(xlToRight).Column - 1 '取得した年月の最大値と最小値を求めて、最小値から最大値までを1ヶ月間隔で転記していく With WorksheetFunction datMax = .Max(Range(Cells(lngFromRowsNo, 4), Cells(lngFromRowsNo, ec))) datMin = .Min(Range(Cells(lngFromRowsNo, 4), Cells(lngFromRowsNo, ec))) End With ' 次の行へ lngToRowsNo = lngToRowsNo + 1 End If Next lngFromRowsNo End Sub
hatena19

2020/09/29 15:21

回答に追記しましたので参照してください。
icecleam

2020/09/29 15:28 編集

今参照をして、実行して見たところそれぞれの最大値と最小値を取得することができました! あと申し訳ないのですが、これを質問の「転記先」のように転記するにはどうすれば良いのでしょうか。。
hatena19

2020/09/29 16:58

kuma_kuma_ さんの回答の2番目のコードと組み合わせれば、全体の最大値と最小値が求められます。 全体の最大値と最小値が求められたら、下記のコードで転記先に転記できます。 Dim ToColumnNo As Long ToColumnNo = 4 Do wsTo.Cells(2, ToColumnNo).Value = datMin ToColumnNo = ToColumnNo + 1 '次の列へ datMin = DateAdd("m", 1, datMin) '一ヶ月後 Loop Until datMin > datMax
icecleam

2020/10/01 22:00 編集

ありがとうございます。 今、上記の対応をしようとしていたのですが、以下のように組み合わせて実行したら、またまた「オブジェクト変数またはWithブロック変数が設定されていません」というエラーメッセージが出てしまいました。 正常に実行するにはどう修正すれば良いでしょうか。。 ラリーが長くなってしまい申し訳ありませんが、お付き合いいただけると幸いです。。 [追記] 質問の内容にも、ここまでご回答いただいた内容を反映させていただきました。 可能であれば、ご回答をいただきたいです。。 ソース ----- Sub SheetTenki() ' Dim ec As Long '年月の一番左から一番右までを取得 Dim lngFromRowsNo As Long ' 検索する行位置 Dim lngToRowsNo As Long ' 書きこむ行位置 Dim wsFrom As Worksheet ' 取得側Excelシート Dim wsTo As Worksheet ' 設定側Excelシート Dim datMax As Date '日付最大値 Dim datMin As Date '日付最小値 Dim enddatMax As Date ' 最終的な日付最大値 Dim enddatMin As Date '最終的な日付最小値 Dim ToColumnNo As Long enddatMax = #1/1/100# '日付最大値に最小値を設定 enddatMin = #1/1/9999# '日付最最少値に最大値を設定 ToColumnNo = 4 'シート"質問1"を選択 Set wsFrom = Worksheets("質問1") 'D列を上から検索していき、yyyy/mm/dd形式のセルを抽出する For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count If IsDate(wsFrom.Cells(lngFromRowsNo, 4).Value) Then '抽出した行の年月を値が含まれる最大まで(右側)取得 '?1は見込み合計を含まないため ec = wsFrom.Cells(lngFromRowsNo, 4).End(xlToRight).Column - 1 '取得した年月の最大値と最小値を求めて、最小値から最大値までを1ヶ月間隔で転記していく With WorksheetFunction datMax = .Max(Range(wsFrom.Cells(lngFromRowsNo, 4), wsFrom.Cells(lngFromRowsNo, ec))) datMin = .Min(Range(wsFrom.Cells(lngFromRowsNo, 4), wsFrom.Cells(lngFromRowsNo, ec))) End With 'どこに転記するか不明なのでとりあえずメッセージボックスに表示 'MsgBox "最大値:" & datMax & " 最小値:" & datMin If enddatMin > datMin Then enddatMin = datMin End If If enddatMax < datMax Then enddatMax = datMax End If ' 次の行へ lngToRowsNo = lngToRowsNo + 1 End If Next lngFromRowsNo Do wsTo.Cells(2, ToColumnNo).Value = enddatMin ToColumnNo = ToColumnNo + 1 '次の列へ enddatMin = DateAdd("m", 1, enddatMin) '一ヶ月後 Loop Until enddatMin > enddatMax End Sub
hatena19

2020/10/02 01:43

Set wsFrom = Worksheets("質問1") の後に、下記のコードを追加してみてください。 Set wsTo = Worksheets("質問2")
icecleam

2020/10/02 10:54

Set wsTo = Worksheets("質問2") を追記したら無事に実行できました! 本当に助かりました、ありがとうございました!
icecleam

2020/10/05 04:32

すみません、もしよければお答えいただきたいのですが 今回のプログラムでdate関数を使用している箇所をStringで表現し、出力する際には日の部分を出力しないようにしたいのですが、その場合はどのような修正をすれば良いでしょうか。 お手数ですが教えていただければ幸いです。
hatena19

2020/10/05 05:04

wsTo.Cells(2, ToColumnNo).Value = enddatMin この部分のことでしょうか。下記のようにすれば年月の表示になると思います。 wsTo.Cells(2, ToColumnNo).Value = Format(enddatMin,"yyyy/mm") ただ、日付(Date型)のままにしておいて、セルの書式設定でユーザ定義書式て yyyy/mm と設定しておく方がいいと思います。
guest

0

まずLike演算子を使いましょう

VBA

1If 値 like "####/*#/*#" then 2'年月日 3ElseIf 値 like "####/*#" then 4'年月 5ENDIF

VBA

1Dim datMax as Date '日付最大値 2Dim datMin as Date '日付最小値  3datMax = #100/01/01# '日付最大値に最小値を設定 4datMin = #9999/01/01# '日付最最少値に最大値を設定 5'あとはループして文字列を日付型に変換し大小判定して代入していく 6 7If datMin > 値 Then 8 datMin = 値 9ENd If 10If datMax < 値 Then 11 datMax = 値 12ENd If 13

文字列からDate型に変換するのはCDateを使う

VBA

1Dim datDate as Date 2datDate = CDate("2020/09/28")

投稿2020/09/27 23:02

kuma_kuma_

総合スコア2506

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問