Option Explicit

'===========================================================
' 部品_シートコピー / CopySheet
'   ・指定したシート（Worksheet）を、指定した別のシートの「後ろ」へ、コピーする（値・数式・書式のすべて）
'     → Copies the specified sheet (Worksheet) to just after another specified sheet (values, formulas and formats).
'
'   ・雛形のシートをコピーして、帳票を作る、などに使う（コピーしたシートの名前は、シート名変更の部品で付ける）
'     → Used e.g. to copy a template sheet to make a report (name the copy with the rename component).
'
'   ※ この部品は Sub（プロシージャ）ではなく「Function（関数）」で、成功／失敗を Boolean で返す
'     → ※ This component is a Function (not a Sub) that returns success/failure as a Boolean.
'===========================================================

'===========================================================
' ■区分 / Classification
'   ・基礎区分：土台 ／ 用途区分：処理 ／ 操作対象区分：シート
'     → Base: foundation / Purpose: process / Target: sheet
'
' ■バージョン / Version
'   ・Version 1.0（2026-10-30）
'===========================================================

'===========================================================
' ■URL（WordPress部品ページ）
'   https://feelcodelab.com/vba_parts/copysheet/
'===========================================================

'===========================================================
' ■前提条件（AI誤動作防止の最重要項目） / Preconditions
'   ・【最重要】この部品は Function（関数）であり、戻り値（Boolean）を返す
'     → コピーできた場合は True、実行時にできなかった場合は False（この場合は、エラーでは止まらない）
'     → 呼び出し側は、必ず戻り値を確認してから後続処理を行い、メッセージも呼び出し側で表示する
'       （False のときは、MsgBox のあとに Exit Sub まで書く）
'     → [MOST IMPORTANT] This component is a Function that returns a Boolean: True if it worked, False if it
'        failed at run time (no error is raised then). The caller must check the return value before the
'        following processing and show any message itself (write Exit Sub after the MsgBox).
'
'   ・【最重要】コピー元（vSrcWs）と、コピーの位置の基準（vAfterWs）は、どちらも Worksheet で渡す
'     → ブックは、Worksheet が持っているので、ブックの引数は不要。vAfterWs が別のブックのシートなら、そのブックへコピーする
'     → ブックの最後へコピーしたいときは、そのブックの最後のシートを、vAfterWs に渡す
'       （例：wbDst.Worksheets(wbDst.Worksheets.Count)）
'     → [MOST IMPORTANT] Pass Worksheets for both. A Worksheet carries its own workbook; if vAfterWs belongs
'        to another workbook, the sheet is copied into that workbook.
'
'   ・コピーされたシートの名前は、Excel が、自動で付ける（例：「雛形 (2)」）。名前を付けたいときは、
'     コピーの直後に、シート名変更の部品を使う
'     → The copy gets an automatic name by Excel (e.g., "Template (2)"); rename it with the rename component.
'
'   ・同じブック内へコピーした直後は、コピーしたシートが、そのブックの、アクティブなシートになる
'     → 転記系の部品の、シート名 "ActiveSheet" の指定は、この動きを使う
'     → 別のブックへコピーした場合は、動きを確認してから使う（確認していない）
'     → After copying within the same workbook, the copy becomes the active sheet of that workbook; if copied
'        into another workbook, check the behavior before relying on it (not verified).
'
'   ・コピーされるのは、値・数式・書式のすべて。シートの中の、ボタンや図形も、コピーされる
'     → Values, formulas, formats, and the shapes on the sheet are all copied.
'
'   ・非表示のシートも、コピーできる（コピーも、非表示のまま）
'     → A hidden sheet can also be copied (the copy stays hidden).
'
'   ・ブックの構成が保護されているときなど、実行時にできなかった場合は False を返す（原因は、イミディエイトウィンドウに出る）
'     → If the workbook structure is protected or the copy fails otherwise, False is returned (the cause is printed).
'
'   ・設定の誤りは、False ではなく、原因を示すエラーで止まる（Err.Raise）
'     - コピー元・位置の基準が Nothing（vbObjectError + 1006）
'     → A Nothing sheet stops with an error naming the cause.
'
'   ・Offset / Find / Resize / With は禁止
'     → Offset, Find, Resize, and With statements are prohibited.
'===========================================================

'===========================================================
' ■依存関係（部品名明記） / Component Dependencies
'   ・他の部品を参照しない（土台）
'     → References no other component (foundation).
'
'   ・組み合わせ：シートコピー → シート名変更
'     （コピーした直後の、アクティブなシートに、名前を付ける）
'     → Typical combination: [CopySheet] -> [RenameSheet]
'
'   ・組み合わせ：シート存在チェック → シートコピー
'     （コピー元の雛形シートが、あるかを、先に確認する）
'     → Typical combination: [SheetExists] -> [CopySheet]
'
'   ・組み合わせ：シートコピー → 転記_セル単位 / 転記_列単位
'     （コピーした帳票へ、転記する。転記先のシート名は "ActiveSheet" と書く）
'     → Typical combination: [CopySheet] -> [TransferCell_WithMap] / [TransferColumn_WithMap]
'
'===========================================================

'===========================================================
' ■依存関係（シート・表） / Sheet Dependencies
'   ・コピー元（vSrcWs）と、基準のシート（vAfterWs）は、どちらも Worksheet で渡す（ブックの引数は不要）
'     → Pass both the source sheet (vSrcWs) and the reference sheet (vAfterWs) as Worksheets; no workbook argument is needed.
'
'   ・コピーしたシートは、基準のシートの後ろに作られる。名前は、Excel の標準の動き（コピー元の名前に連番）になる
'     → The copy is placed after the reference sheet and gets Excel's default name (the source name plus a number).
'
'   ・コピー直後のシートは、アクティブになる（名前は、シート名変更で付ける）
'     → The new copy becomes the active sheet right after copying; give it a name with [RenameSheet].
'===========================================================

'===========================================================
' ■技術解説 / Technical Notes
'
'   ・Worksheet で受け取る理由
'       → シートそのものを操作する部品は、Worksheet で受け取る（ルール 1-1）。シートは、自分のブックを持っているので、ブックの引数が要らず、別のブックへのコピーも、同じ形で書ける。
'       → A sheet-operating component receives a Worksheet; it carries its own workbook, so a copy into another workbook needs no extra argument.
'
'   ・コピーの位置を、Before ではなく After にする理由
'       → ブックの最後へ追加する使い方が多く、「最後のシートの後ろ」で、書けるため。位置の指定の種類を、増やすと、取り違えやすくなる。前へ入れたいときは、別の部品にする（迷ったら分ける）。
'       → Appending at the end is the most common use; one position type avoids mix-ups.
'
'   ・コピーに失敗したときに、False を返す理由
'       → ブックの構成の保護などで、コピーが失敗することがある。呼び出し側が、戻り値で確認できるようにして、メッセージやエラー処理は、呼び出し側で調整できるようにしている。原因は、Debug.Print に出る。
'       → Copying can fail (e.g., protected workbook structure); the Boolean return value lets the caller check.
'
'   ・確認を On Error GoTo より前に置く理由
'       → On Error GoTo ErrHandler の有効な範囲でエラーを出すと、False に変えられてしまい、原因が伝わらない。
'       → Raising inside the On Error range would turn it into False and hide the cause.
'
'   ・Offset / Find / Resize / With を禁止する理由
'       → 生成AIが誤って不正な範囲操作を行う可能性が高く、行数可変の処理で誤動作を引き起こしやすいため。
'       → These statements often cause misaligned or ambiguous range operations when generated by AI.
'===========================================================

'---------------------------------------------
' ■引数（型＋意味） / Arguments
'   vSrcWs      : コピー元のシート（Worksheet）。雛形のシートなど
'                  → Source sheet (Worksheet), e.g., a template sheet.
'
'   vAfterWs    : コピーの位置の基準のシート（Worksheet）。このシートの「後ろ」へ、コピーする
'                  → Reference sheet (Worksheet); the copy is placed just after it.
'---------------------------------------------

'---------------------------------------------
' ■戻り値（型＋意味） / Return Value
'   Boolean : コピーできた場合は True、実行時にできなかった場合は False
'             → True if copied, False if it failed at run time.
'---------------------------------------------

'---------------------------------------------
' ■エラー / Errors (Err.Raise)
'   ・vbObjectError + 1006：コピー元（vSrcWs）または位置の基準（vAfterWs）が Nothing
'---------------------------------------------

'===========================================================
' ■禁止事項（AI向け） / Prohibitions
'   ・Function を Sub（プロシージャ）に変更することの禁止
'     → Do not convert this Function into a Sub; the Boolean return value is essential.
'
'   ・戻り値（Boolean）を確認せずに後続処理を行うことの禁止
'     → Do not proceed without checking the Boolean return value.
'
'   ・Set していない Worksheet 変数を渡すことの禁止
'     → Do not pass a Worksheet variable that has not been set.
'
'   ・Select / Activate / Selection を使った、シートのコピーの禁止
'     → Do not copy sheets with Select / Activate / Selection.
'
'   ・コピーしたシートの名前を、"○○ (2)" のまま使うことの禁止（シート名変更で、名前を付ける）
'     → Do not rely on the automatic name; rename the copy.
'
'   ・Offset禁止 / Find禁止 / Resize禁止 / With禁止
'     → Offset, Find, Resize, and With blocks are prohibited.
'===========================================================

'===========================================================
' ■使用例（サンプルコード） / Example
'   ◆例：雛形のシートをコピーして、名前を付け、転記する / Example: copy a template, name it, and transfer into it◆
'   Dim wbDst As Workbook
'   Dim wsTemplate As Worksheet
'   Dim wsLast As Worksheet
'
'   If 部品_ファイルを開く("E:\TEST\帳票.xlsx") = False Then MsgBox "開けませんでした": Exit Sub
'   Set wbDst = ActiveWorkbook                                 '開いた直後に控える
'
'   If 部品_シート存在チェック(wbDst, "雛形") = False Then MsgBox "雛形がありません": Exit Sub
'   Set wsTemplate = wbDst.Worksheets("雛形")
'   Set wsLast = wbDst.Worksheets(wbDst.Worksheets.Count)       'ブックの最後のシート
'
'   If 部品_シートコピー(wsTemplate, wsLast) = False Then MsgBox "コピーに失敗しました": Exit Sub
'
'   '→ コピーしたシートは、アクティブになる。名前を付けるには、シート名変更を使う
'   If 部品_シート名変更(wbDst.ActiveSheet, "2026年10月") = False Then MsgBox "名前を変更できませんでした": Exit Sub
'
'   ※ コピー元・位置の基準が Nothing の場合は、False ではなく、原因を示すエラーで止まる
'===========================================================

'===========================================================
' ■ラッパー関数（日本語名） / Wrapper Function
'   ・辞書の日本語名で呼び出すための窓口
'     → Entry point callable by the Japanese dictionary name.
'
'   ・内部では英語名の本体処理を呼び出し、結果（Boolean）をそのまま返す
'     → Internally calls the English-named core function and returns its result (Boolean) as it is.
'===========================================================
Function 部品_シートコピー( _
        ByVal vSrcWs As Worksheet, _
        ByVal vAfterWs As Worksheet) As Boolean

    '本体処理（英語名）を呼び出し、結果をそのまま返す / Call core function and return its result
    部品_シートコピー = f_CopySheet(vSrcWs, vAfterWs)

End Function

'===========================================================
' ■本体処理（英語名） / Core Function
'   ・コピー元のシートを、基準のシートの後ろへ、コピーする
'     → Copies the source sheet to just after the reference sheet.
'===========================================================
Function f_CopySheet( _
        ByVal vSrcWs As Worksheet, _
        ByVal vAfterWs As Worksheet) As Boolean

    f_CopySheet = False

    '---------------------------------------------
    ' ■シートが設定されているかを確認（Nothing の場合はエラーで止める）
    '   ※ On Error GoTo より前に置く（Err.Raise を False に変えず、呼び出し側へ届けるため）
    '   / Check that the sheets are set (stop with an error if Nothing);
    '     placed before On Error GoTo so that Err.Raise reaches the caller
    '---------------------------------------------
    If vSrcWs Is Nothing Then
        Err.Raise vbObjectError + 1006, "f_CopySheet", _
                  "コピー元のシート（vSrcWs）が設定されていません（Nothing）。"
    End If

    If vAfterWs Is Nothing Then
        Err.Raise vbObjectError + 1006, "f_CopySheet", _
                  "コピーの位置の基準のシート（vAfterWs）が設定されていません（Nothing）。"
    End If

    '---------------------------------------------
    ' ■エラー時は ErrHandler へ（False を返す） / On error, jump to ErrHandler (returns False)
    '---------------------------------------------
    On Error GoTo ErrHandler

    '---------------------------------------------
    ' ■コピー（基準のシートの後ろへ） / Copy (just after the reference sheet)
    '---------------------------------------------
    vSrcWs.Copy After:=vAfterWs

    f_CopySheet = True
    Exit Function

ErrHandler:
    Debug.Print "f_CopySheet: " & Err.Number & " " & Err.Description
    f_CopySheet = False

End Function

