[[20251028132238]] 『指定期間の年月をばらして月ごとに入力する方法』(bot) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) |

| 全文検索 | 過去ログ ]

 

『指定期間の年月をばらして月ごとに入力する方法』(bot)

関数でもVBAでも方法は問わず、表に入力した年月を月ごとにばらして、他の表に入力する方法があれば教えていただきたいです。
開始日と終了日は行ごとに変わります。

(例)

(表A)
開始日    終了日
2025年1月  2025年3月
2025年6月  2026年2月


(表B)
2025年1月
2025年2月
2025年3月

2025年6月
2025年7月



2026年2月

< 使用 Excel:Microsoft365、使用 OS:Windows11 >


セルに
2025年1月
と書いて必要分下にフィルドラッグ

セルに
2025年6月
と書いて必要分下にフィルドラッグ

すればいいだけでは
(不明) 2025/10/28(火) 13:50:59


 (表A)の
 開始日がA:A5、終了日がB2:B5 だとすると

 (表B)のいずれかのセルに
 =SORT(TOCOL(A2:B5),,1)

 とか。

(通りすがり) 2025/10/28(火) 14:01:34


行ごとの出力であれば以下の式でいけますが、表Aを一度に、という式は私では無理でした。
他の人の回答をお待ち下さい。

 =EOMONTH(A1,SEQUENCE(TEXT(B1-A1,"y")*12+TEXT(B1-A1,"m")+1,,-1))+1

(傘) 2025/10/28(火) 14:12:50


 私も1行単位であれば
 =UNIQUE(TEXT(ROW(INDIRECT(TEXTJOIN(":",,A2:B2))),"yyyy!年m!月"))
 とできたがVSTCK関数で重ねるのがうまくいかなかった。

(ねむねむ) 2025/10/28(火) 14:25:01


 傘さんの式を試していたところ、
 開始日を
 2025年10月
 で、終了日を下記のようにしたところ最終月が右のようになった。
 2025年10月   2025年11月
 2025年12月      2026年1月
 2026年1月       2026年2月
 2026年2月       2026年3月
 4月以降、11月までは正しく、2026年12月でまたひと月余計になるようだ。
(ねむねむ) 2025/10/28(火) 14:37:13

ありゃ、本当ですね
月の算出を日数の引き算でやってるから31日まである月が絡んだ時にうまく計算できてないみたい
(傘) 2025/10/28(火) 14:53:04

 DATEDIF関数つかっちゃいましたが
 =TEXT(TEXTSPLIT(TEXTJOIN(",",,BYROW(A2:B3,LAMBDA(r,LET(s,INDEX(r,1,1),e,INDEX(r,1,2),ARRAYTOTEXT(EOMONTH(s,SEQUENCE(DATEDIF(s,e,"M")+1,,-1))+1))))),,","),"yyyy年m月")
(´・ω・`) 2025/10/28(火) 15:02:44

生成AIの回答です。

Excelで指定された期間を月ごとにばらして入力する方法をいくつかご紹介します。ここでは、関数を使う方法とVBAを使う方法の2つを説明します。

### 方法1: Excel関数を使用

以下の手順で、関数を使って月ごとにばらします。

1. **表Aの作成**

   A列に「開始日」、B列に「終了日」を入力します。

   A1: 開始日       B1: 終了日
   A2: 2025年1月    B2: 2025年3月
   A3: 2025年6月    B3: 2026年2月

2. **月リストを作成するシート**

   任意のシート(例: 表B)を作成します。

3. **月数計算のセルを作成**

   表Bに月を列挙するため、次のように入力します。

   A1セルに以下の数式を入力します。
   =IFERROR(EDATE($A$2, ROW(A1)-1), "")

   ここで、$A$2は開始日が入っているセルを参照しています。

4. **月ごとの範囲を指定**

   入力したい開始日から終了日までのセルを参照しながら、次のように入力します。月数を算出するために、以下のように少し複雑な数式を使います。

   A2セルに次の数式を入力します。
   =IF(ROW(A1)+SUMPRODUCT(((ROW($A$2:$A$3)<=ROW($A$2)*(ROW($B$2:$B$3)>=ROW($A$2)))*(MONTH($A$2:$A$3)=MONTH($A$2)+INT((ROW(A1)-1)/12)))*(DATE(YEAR($A$2), MONTH($A$2)+MOD((ROW(A1)-1),12), 1))<>""), 1), DATE(YEAR($A$2), MONTH($A$2)+MOD(ROW(A1)-1,12), 1), "")

5. **数式を下にコピー**

   必要な行数だけ下にコピーして、各月がリストされるようにします。

### 方法2: VBAを使用

VBAを使って、指定した期間を月ごとにばらして自動的に入力することもできます。

Sub SplitMonths()

    Dim wsA As Worksheet, wsB As Worksheet
    Dim startRow As Long, endRow As Long
    Dim i As Long, monthCount As Long, j As Long
    Dim startDate As Date, endDate As Date
    Dim currentRow As Long

    ' シートの設定
    Set wsA = ThisWorkbook.Sheets("Sheet1") ' 表Aのシート名を指定
    Set wsB = ThisWorkbook.Sheets("Sheet2") ' 表Bのシート名を指定

    ' 表Aの行数を取得
    startRow = 2
    endRow = wsA.Cells(wsA.Rows.Count, 1).End(xlUp).Row

    currentRow = 1

    ' 表Aをループして月を展開
    For i = startRow To endRow
        startDate = wsA.Cells(i, 1).Value
        endDate = wsA.Cells(i, 2).Value
        monthCount = DateDiff("m", startDate, endDate)

        For j = 0 To monthCount
            wsB.Cells(currentRow, 1).Value = Format(DateAdd("m", j, startDate), "yyyy年m月")
            currentRow = currentRow + 1
        Next j
    Next i
End Sub

### まとめ

(AI頼み) 2025/10/28(火) 15:30:35


AIさんにきいたらこんな答えだった

以下に、いくつかの方法を提案します:

【方法1】VBA(マクロ)を使用する方法
Sub 年月展開()

    Dim ws1 As Worksheet, ws2 As Worksheet
    Dim i As Long, j As Long, rowCount As Long
    Dim startDate As Date, endDate As Date

    Set ws1 = ThisWorkbook.Sheets("表A")
    Set ws2 = ThisWorkbook.Sheets("表B")

    ws2.Cells.Clear
    rowCount = 2

    For i = 2 To ws1.Cells(Rows.Count, 1).End(xlUp).Row
        startDate = CDate(ws1.Cells(i, 1).Value)
        endDate = CDate(ws1.Cells(i, 2).Value)

        Do While startDate <= endDate
            ws2.Cells(rowCount, 1).Value = Format(startDate, "yyyy年m月")
            startDate = DateAdd("m", 1, startDate)
            rowCount = rowCount + 1
        Loop
    Next i
End Sub

【方法2】数式(配列数式)を使用する方法

1. C列に以下の数式を入力(配列数式として):
=SEQUENCE(DATEDIF(A2,B2,"M")+1,1,A2,EOMONTH(A2,0))

2. D列に以下の数式を入力:
=TEXT(C2,"yyyy年m月")

【方法3】Power Query(データ)を使用する方法

1. 「データ」>「データの取得」>「テーブルまたは範囲」
2. 範囲を選択
3. 変換タブ>「列の追加」>「カスタム列」

カスタム列エディターで以下のM言語スクリプトを入力:
let

    #"開始日" = #"元のテーブル"[開始日],
    #"終了日" = #"元のテーブル"[終了日],
    #"月のリスト" = List.Generate(
        () => #"開始日",
        each _ <= #"終了日",
        each Date.AddMonths(_, 1)
    ),
    #"テーブルに変換" = Table.FromList(
        #"月のリスト", 
        Splitter.SplitByNothing(), 
        {"年月"}
    ),
    #"形式の変更" = Table.TransformColumns(
        #"テーブルに変換",
        {{"年月", each Text.From(_, "ja-JP")}}
    )
in
    #"形式の変更"

各方法に長所短所がありますので、用途に応じて選択してください。

【推奨】

(AI頼り) 2025/10/28(火) 15:35:28


ご指定の通り、開始日と終了日の年月を月ごとに分解して別の表(表B)に出力する方法を説明します。方法は関数ベース(VBA不要)とVBAベースの2つを提案します。どちらもWindows 11上で動作確認可能です。

前提として、年月は「2025年1月」のような文字列形式と仮定します。これをExcelの日付として扱うために、まず日付に変換します(例: 「2025年1月」→ 2025/1/1)。

### 準備: 表Aの設定例

これを基に、別のシート(例: シート2)で表Bを作成します。

### 方法1: 関数を使う(VBA不要、Microsoft 365推奨)
Microsoft 365の動的配列関数(SEQUENCE, TEXT, DATEなど)を使って、自動的に月リストを生成します。複数の行に対応し、開始/終了が変更されても自動更新されます。

#### ステップ1: 年月を日付に変換するヘルパー列を作成

  =DATE(LEFT(A2,4),RIGHT(A2,LEN(A2)-FIND("年",A2))+1,1)
  - 説明: 「2025年1月」から年と月を抜き出し、DATE関数で2025/1/1に変換。
  =DATE(LEFT(B2,4),RIGHT(B2,LEN(B2)-FIND("年",B2))+1,1)

#### ステップ2: 表Bを生成(シート2で)

  =LET(
      starts, Sheet1!C2:C3,  // 開始日の日付列(範囲を実際の行数に合わせて調整)
      ends, Sheet1!D2:D3,    // 終了日の日付列
      rows, SEQUENCE(ROWS(starts)),  // 行番号
      months_per_row, DATEDIF(starts, ends, "m") + 1,  // 各行の月数
      total_months, SUM(months_per_row),  // 合計月数
      seq, SEQUENCE(total_months),  // 全体のシーケンス
      cumsum, SCAN(0, months_per_row, LAMBDA(acc, val, acc + val)),  // 累積月数
      row_index, XLOOKUP(seq, cumsum + 1, rows, , -1),  // 各月の行インデックス
      month_offset, seq - INDEX(cumsum, row_index),  // 月のオフセット
      base_months, EOMONTH(INDEX(starts, row_index), month_offset - 1),  // 月計算
      VSTACK(
          TEXT(base_months, "yyyy年m月"),  // 年月形式に変換
          ""  // 行間の空行(任意)
      )
  )

  - **説明**:
    - LET関数で変数を定義し、計算を整理。
    - DATEDIFで各行の月数を計算。
    - SEQUENCEで月リストを生成し、EOMONTHで月を進める。
    - TEXTで「2025年1月」の形式に変換。
    - VSTACKでリストを縦に結合(行間に空行を挿入可能)。
  - 範囲(C2:C3など)は表Aの行数に合わせて調整してください。行が増えたら範囲を広げて再計算。

#### 利点と注意

### 方法2: VBAを使う(マクロで柔軟に)
VBAでマクロを作成し、ボタンクリックで表Bを生成。行数が多い場合やカスタマイズしやすい。

Sub GenerateMonthList()

    Dim wsA As Worksheet, wsB As Worksheet
    Dim startRow As Long, endRow As Long
    Dim i As Long, j As Long
    Dim startDate As Date, endDate As Date
    Dim currentMonth As Date
    Dim outputRow As Long

    Set wsA = ThisWorkbook.Sheets("Sheet1")  ' 表Aのシート名
    Set wsB = ThisWorkbook.Sheets("Sheet2")  ' 表Bのシート名
    startRow = 2  ' 表Aのデータ開始行
    endRow = wsA.Cells(Rows.Count, "A").End(xlUp).Row  ' 最終行を自動検出

    wsB.Cells.Clear  ' 表Bをクリア
    outputRow = 1

    For i = startRow To endRow
        ' 年月を日付に変換(エラー処理付き)
        On Error Resume Next
        startDate = DateValue(Replace(Replace(wsA.Cells(i, "A").Value, "年", "/"), "月", "/1"))
        endDate = DateValue(Replace(Replace(wsA.Cells(i, "B").Value, "年", "/"), "月", "/1"))
        On Error GoTo 0

        If startDate > 0 And endDate > 0 And startDate <= endDate Then
            currentMonth = startDate
            Do While currentMonth <= endDate
                wsB.Cells(outputRow, "A").Value = Format(currentMonth, "yyyy年m月")
                outputRow = outputRow + 1
                currentMonth = DateAdd("m", 1, currentMonth)  ' 翌月へ
            Loop
            outputRow = outputRow + 1  ' 行間に空行を挿入
        End If
    Next i
End Sub

#### 利点と注意

### 追加Tips

by Grok

(Groky) 2025/10/28(火) 15:49:37


有識者の皆様ありがとうございます。
たくさん回答いただけたので一つずつ試してみます。
AIに質問する発想がなかったので、今後参考にいたします。
ありがとうございました。
(bot) 2025/10/28(火) 16:11:44

 AIの回答を載せているかたに確認します。
 回答者として、AIの回答を確認しておられるのでしょうか。

 間違ったAIの回答をそのまま載せるのはいかがなものかと思います。
 例えば、Excelの数式中に  // というコメントを入れることなどできないですよ。
 一目見ておかしいです。

 ご自分である程度確認の上で、回答してもらえませんか?

(xyz) 2025/10/28(火) 16:25:04


 これって、A列,B列に
 2025年1月という文字列が入っているのか
 2025/1/1 という日付が入っていて、書式の表示形式で "yyyy年m月" にしてあるのかで
 式を変えないといけない場合があると思うのですけれど、どちらですか?

 回答者のみなさんは、どちらを前提に回答してますか?(AIに回答させてますか)
(´・ω・`) 2025/10/28(火) 16:36:19

私の式は文字列での使用は想定してませんでしたが、日付でも文字列でも問題ないようですね(他の問題があるけど)

これといった関数の無い月の差分計算ですけど、表記が○年×月で日付は1日想定なら

 =ROUND((後-前)/30.4,0)

とかいう力技が一番簡単な気がしてきた…
(傘) 2025/10/29(水) 09:00:27


 (´・ω・`)さんが示されたように、
 BYROWを使って、各行ごとに年月を文字列として連結したものを算出するのが良いと思いました。
 一方、年月(各月の1日のDate値)の配列を直接的にVSTACKしていくとすれば、次のような感じになるかと思います。

 =LET(
     rng,A1:B4,
     n,ROWS(rng),
     a,REDUCE("",SEQUENCE(n),
         LAMBDA(accum,x,
             LET(st,INDEX(rng,x,1),
                 en,INDEX(rng,x,2),
                 m,DATEDIF(st,en,"M")+1,
                 m_array,DATE(YEAR(st),SEQUENCE(m,,MONTH(st),1),1),
                 VSTACK(accum,m_array)
             )
         )
     ),
     DROP(a,1)
 )
 ご参考まで。

 # データはDateのシリアル値を表示変換したものと受け止めました。
 # 上記の式もシリアル値を返すので、適切な表示形式を指定する必要があります。
(xyz) 2025/10/29(水) 09:40:37

 こんなのも。
=DROP(REDUCE("",A2:A3,LAMBDA(s,t,VSTACK(s,EDATE(t,SEQUENCE(DATEDIF(t,OFFSET(t,,1),"M")+1,,0))))),1)
(んなっと) 2025/10/29(水) 16:49:59

 OFFSETを使いたくないときは
=DROP(REDUCE("",A2:A3,LAMBDA(s,t,VSTACK(s,EDATE(t,SEQUENCE(DATEDIF(t,INDEX(B:B,ROW(t)),"M")+1,,0))))),1)
(んなっと) 2025/10/29(水) 16:52:12

 んなっとさん、いつもながら鮮やかなものですね。ためになりました。ありがとうございます。

(xyz) 2025/10/31(金) 11:42:40


 (Groky)さんの回答 2025/10/28(火) 15:49:37 についてのコメントです。

 ワークシート関数の回答は間違っています。
 最初のSheet1の式から間違っていますし、
 Sheet2に入れるべき数式も間違っています(コメントは削除したうえでも間違っています)
 こういう場合は、まずGrokに再検討をさせて、正しいものを再投稿して頂きたいですね
 (なお、VBAの回答は見ていません。間違いようがないような例かと思料します)

   -----------
 (AI頼り)さんの回答 2025/10/28(火) 15:35:28 についてのコメントです。

 Power Query使用の回答ですが、回答どおりに実行するとエラーになります。
 これも生成AIに再質問して、正しい結果が返るものを再提示して頂きたいですね。
 詳細エディターに入れるべきコードを提示してもらうとありがたい。

(xyz) 2025/10/31(金) 11:47:00


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.