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

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

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

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

Q&A

解決済

4回答

1314閲覧

【VBA】入れ子のFor文が期待通りの処理をしない

hasune

総合スコア18

VBA

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

0グッド

0クリップ

投稿2020/09/30 04:10

VBAのネストしているFor文が期待通りに実行されません。

以下に現状をまとめました。

【作業環境】
Windows 7 Professional
Excel 2007

【やりたいこと】
テンプレートシート(オブジェクト名:wsTemplate2)
→E2セルから右に開始日~終了日までを表示

【困っていること】
テンプレートシートのE2セルから右に開始日~終了日までが表示されない。

現状は以下の通り。

①E2~AD2まで「1900/1/31」が入る

②本来なら日付はE2~AI2まで入る。データの個数が4つ足りない

【参照データ】
カレンダーシート(オブジェクト名:wsDateList)
→D2セル「2021/01/01」(開始日)
→E2セル「2021/01/31」(終了日)

【試したこと】
・For文を入れ子にぜずにそれぞれの処理をイミディエイトで確認したところ、
期待通りの処理になった
→入れ子にすると期待通りの処理にならない

イミディエイトで動きを確認したところ、
入れ子になっているFor文のどちらも正しく機能していません。
日付は2021/01/28から始まっており、
21個ずつ同じものが表示されています。
列の移動も9(I列)から始まっていますが、
テンプレートシートには5(E列)から表示されています。

VBAの勉強中であるため分かりにくい箇所があるかもしれませんが、
どうぞよろしくお願いいたします。

Public Sub template() Dim dateStartDate As Date '開始日 Dim dateEndDate As Date '終了日 Dim loncntDay As Long '開始日~終了日の日数カウント用変数 Dim Dayone As Date '日付用変数 Dim cntColl As Long '列変数 dateStartDate = wsDateList.Range("D2") '「開始日」 dateEndDate = wsDateList.Range("E2") '「終了日」 loncntDay = DateDiff("d", dateStartDate, dateEndDate) '「開始日」~「終了日」を日単位で数える For Dayone = 0 To loncntDay '開始日から1日単位で増えていく(※開始日も表示したいので0からスタート) For cntColl = 5 To loncntDay '列移動 wsTemplate2.Cells(2, cntColl).Value = DateAdd("d", 1, Dayone) '1~開始日-終了日の日数 Debug.Print DateAdd("d", Dayone, dateStartDate) Debug.Print "2, "; cntColl Next cntColl Next Dayone End Sub

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

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

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

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

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

guest

回答4

0

解決済みですが、こんな方法も。

vba

1Public Sub template() 2 3 Dim dateStartDate As Date '開始日 4 Dim dateEndDate As Date '終了日 5 dateStartDate = wsDateList.Range("D2").Value 6 dateEndDate = wsDateList.Range("E2").Value 7 8 Dim DateCell As Range 9 Set DateCell = wsTemplate2.Range("E2") '日付入力セル 10 11 Dim Dayone As Date 12 For Dayone = dateStartDate To dateEndDate '開始日から終了日までループ 13 DateCell.Value = Dayone 14 Set DateCell = DateCell.Offset(, 1) ’入力セルを右へ移動 15 Next Dayone 16 17End Sub

Date型も中身は数値型(倍精度浮動小数点型)なのでForでループできます。


ループを使わずにやる方法も。

vba

1Public Sub template1() 2 3 Dim dateStartDate As Date '開始日 4 Dim dateEndDate As Date '終了日 5 Dim loncntDay As Long 6 7 dateStartDate = wsDateList.Range("D2") 8 dateEndDate = wsDateList.Range("E2") 9 loncntDay = DateDiff("d", dateStartDate, dateEndDate) 10 11 wsTemplate2.Range("E2").Value = dateStartDate 12 With wsTemplate2.Range("F2").Resize(, loncntDay) 13 .Formula = "=E2+1" '左のセルに+1 14 .Value = .Value '式を値に変換 15 End With 16 17End Sub

投稿2020/09/30 04:56

編集2020/09/30 05:20
hatena19

総合スコア34075

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

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

hasune

2020/09/30 05:26

解決済みにもかかわらず回答をしてくださりありがとうございます。 Date型も数値なのですね。知らなかったので勉強が足りていませんでした。 VBA初心者の私でも理解できるコードですごく見やすいです。 こんなコードが書けるようよう今後も頑張っていきます。
guest

0

2重ループの必要性はまったくありません。
またDate型は整数値が日を表しているので、単純に開始日にループの値を加算していけばよいです。
という感じで以下のように修正しました。

VBA

1 dateStartDate = wsDateList.Range("D2") '「開始日」 2 dateEndDate = wsDateList.Range("E2") '「終了日」 3 loncntDay = DateDiff("d", dateStartDate, dateEndDate) '「開始日」~「終了日」を日単位で数える 4 cntColl = 5 5 For Dayone = 0 To loncntDay '開始日から1日単位で増えていく(※開始日も表示したいので0からスタート) 6 wsTemplate2.Cells(2, cntColl).Value = dateStartDate + Dayone 7 cntColl = cntColl + 1 8 Next Dayone 9

投稿2020/09/30 04:37

ttyp03

総合スコア17000

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

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

hasune

2020/09/30 04:59

>2重ループの必要性はまったくありません。 指摘をされてようやく気付くことができました。 エクセルで1日単位で加算する場合、 以下の処理になるのだから当然ですね。 A1 B2 C2 1/1 A1+1 B2+1 正しいコードだけでなく、 ご説明までしていただき深く感謝しております。 またひとつVBAの理解が深まりました。
guest

0

ベストアンサー

こんな考え方も。

VBA

1Public Sub template() 2 3 Dim dateStartDate As Date '開始日 4 Dim dateEndDate As Date '終了日 5 dateStartDate = wsDateList.Range("D2").Value '「開始日」 6 dateEndDate = wsDateList.Range("E2").Value '「終了日」 7 8 Dim cntColl As Long '列変数 9 cntColl = 5 10 11 Do While wsTemplate2.Cells(2, cntColl - 1).Value <> dateEndDate '終了日でない間続ける 12 wsTemplate2.Cells(2, cntColl).Value = dateStartDate + cntColl - 5 13 cntColl = cntColl + 1 14 Loop 15 16End Sub

投稿2020/09/30 04:32

編集2020/09/30 04:41
radames1000

総合スコア1925

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

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

hasune

2020/09/30 04:50

Do Whileを使用しての処理は考え付きませんでした。 さらにテンプレートシートに表示される日付がきちんと2021/1/1~2021/1/31になっていて嬉しいです。 2021がどうして1900になるのか調べても上手く理解できなかったためとても助かりました。 ①と②を解決していただいたradames1000さんの回答をベストアンサーとさせていただきます。
guest

0

VBA

1' dateStartDate = wsDateList.Range("D2") '「開始日」 2' dateEndDate = wsDateList.Range("E2") '「終了日」 3 dateStartDate = wsDateList.Range("D2").value '「開始日」 4 dateEndDate = wsDateList.Range("E2").value '「終了日」 5 6コード

Loopはどちらかにしましょう

VBA

1 cntColl = 5 2 For Dayone = 0 To loncntDay '開始日から1日単位で増えていく(※開始日も表示したいので0からスタート) 3 4 wsTemplate2.Cells(2, cntColl + Dayone).Value = DateAdd("d", 1, Dayone) '1~開始日-終了日の日数 5 Debug.Print DateAdd("d", Dayone, dateStartDate) 6 Debug.Print "2, "; cntColl 7 8 Next Dayone 9

投稿2020/09/30 04:24

kuma_kuma_

総合スコア2506

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

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

hasune

2020/09/30 04:39

ループを1つに絞っての処理の方法が思いつかなかったのでとても勉強になります。 ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問