Option Explicit

'===========================================================
' ■部品_範囲消去_値のみ / ClearRange_Contents
'   ・指定した範囲（Range）の、値（入力された内容）だけを消去する
'     → Clears only the values (contents) of the specified range (Range).
'
'   ・消去する範囲は、範囲設定部品（SetRange_Fixed）で作った Range を、そのまま渡す
'     → Pass the Range made by the range-setting component (SetRange_Fixed) as it is.
'
'   ・最終行をどう決めるか（但し書きの行を除く、など）は、範囲を作る呼び出し側で決める
'     → How the last row is decided (e.g., excluding a note below the table) is up to the caller that makes the range.
'
'   ★ この部品は Sub（プロシージャ）ではなく「Function（関数）」で、成功／失敗を Boolean で返す
'     → ★ This component is a Function (not a Sub) that returns success/failure as a Boolean.
'===========================================================

'===========================================================
' ■区分 / Classification
'   ・基礎区分：土台 ／ 用途区分：処理 ／ 操作対象区分：範囲
'     → Base: foundation / Purpose: process / Target: range
'
' ■バージョン / Version
'   ・Version 1.0（2026-10-28）
'===========================================================

'===========================================================
' ■URL（WordPress部品ページ）
'   https://feelcodelab.com/vba_parts/clearrange_contents/
'===========================================================

'===========================================================
' ■前提条件（AI誤動作防止の最重要項目） / Preconditions
'   ★【最重要】この部品は Function（関数）であり、戻り値（Boolean）を返す
'     → 消去できた場合は True、実行時にできなかった場合は False（この場合は、エラーでは止まらない）
'     → 呼び出し側は、必ず戻り値を確認してから後続処理を行い、メッセージも呼び出し側で表示する
'     → ★ [MOST IMPORTANT] This component is a Function that returns a Boolean: True if cleared, 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.
'
'   ★【最重要】範囲（vRng）は、範囲設定部品などで作った Range を渡す（Set 済みであること）
'     → 範囲は、自分がどのブック・どのシートのものかを持っているので、ブックやシート名の引数は不要
'     → ★ [MOST IMPORTANT] Pass a Range that has already been set (e.g., made by SetRange_Fixed). A Range
'        knows its own workbook and sheet, so no workbook or sheet name argument is needed.
'
'   ・消去されるのは「値だけ」（書式・罫線・色・入力規則は残る）
'     → Only the values are cleared; formats, borders, colors and validation remain.
'
'   ・消去は元に戻せない（確認なしで消去される）。消してはいけない行（見出し行など）が、範囲に
'     含まれていないか、呼び出し側で確認する
'     → The clearing cannot be undone and is done without confirmation; the caller must make sure the range
'        does not include rows that must not be cleared (e.g., the header).
'
'   ・設定の誤りは、False ではなく、原因を示すエラーで止まる（Err.Raise）
'       - 範囲（vRng）が Nothing（vbObjectError + 1014）
'     → A Nothing range stops with an error naming the cause (vbObjectError + 1014).
'
'   ・Offset / Find / Resize / With は禁止
'     → Offset, Find, Resize, and With statements are prohibited.
'===========================================================

'===========================================================
' ■依存関係（部品同士） / Component Dependencies
'   ・なし（土台の部品。他の部品を参照しない。単独で使用可能）
'     → No required dependencies; this is a foundation component and is standalone.
'
'   ・組み合わせ：f_SetRange_Fixed → f_ClearRange_Contents
'     （範囲設定_固定で、消す範囲を作ってから、渡す）
'     → Typical combination: [SetRange_Fixed] -> [ClearRange_Contents] (make the range to clear, then pass it).
'
'   ・転記の前に、転記先の範囲を消去する用途で使うことが多い
'     → Often used to clear the destination range before a transfer.
'===========================================================

'===========================================================
' ■依存関係（シート・表） / Sheet Dependencies
'   ・特になし（マッピング表等は不要）
'     → No sheet-level dependencies (no mapping table etc. required).
'===========================================================

'===========================================================
' ■技術解説 / Technical Notes
'
'   ・ブックやシート名ではなく、Range を引数にする理由
'       → 範囲（Range）は、自分がどのブック・どのシートのものかを持っている。
'          範囲設定部品で作った Range を、そのまま渡せば、消す場所の指定が、呼び出しの行に現れる。
'          コピー系の部品（範囲コピー）が、範囲設定部品の Range を使う形と、同じ考え方である。
'       → A Range carries its own workbook and sheet. Passing the Range made by the range-setting component
'          shows the target in the call, in the same way as the copy components.
'
'   ・最終行の取得を、この部品に含めない理由
'       → 最終行の決め方は、表によって違う（表の下に但し書きがある、途中に空白がある、など）。
'          最終行は、呼び出し側が自由に決めて、範囲に反映するほうが、柔軟に使える。
'       → How the last row is decided differs by table (notes below the table, gaps, etc.), so the caller
'          decides it freely and reflects it in the range.
'
'   ・ClearContents を使う理由
'       → ClearContents leaves formats (borders, colors, number formats) as they are, so the table keeps its appearance and only the values are removed.
'
'   ・値だけを消す部品と、すべてを消す部品を、分けている理由
'       → 動きの違いを、部品名で分かるようにして、引数（数字）の取り違えを防ぐため。
'          もう一方の部品は、「部品_範囲消去_すべて」（値と書式のすべてを消す） である。
'       → The difference in behavior is shown by the component name to avoid mixing up argument numbers;
'          the other component is ClearRange_All (clears values and formats).
'
'   ・範囲が Nothing のとき、False ではなく、エラーで止める理由
'       → Set し忘れた Range を渡すと、「消去に失敗した」と、区別がつかなくなる。
'          設定の誤りは、結果（False）として返さず、エラーで止めて原因を示す。
'       → A Range that was never set would be indistinguishable from "clearing failed"; the setting mistake
'          stops with an error naming the cause instead of returning False.
'
'   ・消去できなかった場合に、False を返す理由
'       → シートの保護、結合セルを含む範囲などで、消去が失敗することがある。
'          呼び出し側が、戻り値で確認できるようにして、メッセージやエラー処理は、呼び出し側で調整できるようにしている。
'       → Clearing can fail (protected sheet, merged cells). The Boolean return value lets the caller check
'          the result, while messages and error handling are left to the caller.
'
'   ・Nothing の確認を、On Error GoTo より前に置く理由
'       → On Error GoTo ErrHandler の有効な範囲でエラーを出すと、False に変えられてしまい、原因が伝わらない。
'          確認を前に置くことで、Err.Raise が呼び出し側へ届く。
'       → Raising inside the range where On Error GoTo is active would turn it into False and hide the cause;
'          the check is placed before it so that Err.Raise reaches the caller.
'
'   ・Offset / Find / Resize / With を禁止する理由
'       → 生成AIが誤って不正な範囲操作を行う可能性が高く、行数可変の処理で誤動作を引き起こしやすいため。
'       → These statements often cause misaligned or ambiguous range operations when generated by AI.
'
'   ・本部品が「土台」である理由
'       → 範囲を消す処理は、転記・書き出しなどの前処理として、多くの場面で必要になり、
'          しかも他の部品を参照せずに単独で動くため。
'       → Clearing a range is needed as preparation in many situations, and it works on its own
'          without referencing other components.
'===========================================================

'---------------------------------------------
' ■引数（型＋意味） / Arguments
'   vRng : 消去する範囲（Range）。範囲設定部品などで作った、Set 済みの範囲
'          → Range to clear (Range); already set, e.g., made by the range-setting component.
'---------------------------------------------

'---------------------------------------------
' ■戻り値（型＋意味） / Return Value
'   Boolean : 消去できた場合は True、実行時にできなかった場合は False
'             → True if cleared, False if it failed at run time.
'---------------------------------------------

'---------------------------------------------
' ■エラー / Errors (Err.Raise)
'   ・vbObjectError + 1014：範囲（vRng）が Nothing
'---------------------------------------------

'===========================================================
' ■禁止事項（AI向け） / Prohibitions
'   ・Function を Sub（プロシージャ）に変更することの禁止
'     → Do not convert this Function into a Sub; the Boolean return value is essential.
'
'   ・戻り値（Boolean）を確認せずに後続処理を行うことの禁止
'     → Do not proceed to the following processing without checking the Boolean return value.
'
'   ・Set していない Range 変数を渡すことの禁止
'     → Do not pass a Range variable that has not been set.
'
'   ・消去してはいけない行（見出し行など）を含む範囲を、確認せずに渡すことの禁止
'     → Do not pass a range that includes rows that must not be cleared (e.g., the header) without checking.
'
'   ・セル参照の直書き禁止（Range("A1") など）
'     → Hard-coded cell references are prohibited; make the range with the range-setting component.
'
'   ・Offset禁止
'     → Offset may cause misaligned row calculations.
'
'   ・Find禁止
'     → Find leads to unpredictable search behavior.
'
'   ・Resize禁止
'     → Resize may unintentionally expand ranges.
'
'   ・With禁止
'     → With blocks cause ambiguous object references.
'===========================================================

'===========================================================
' ■使用例（サンプルコード） / Example
'   ＜例1：見出し（2行目）の下のデータを、A列〜D列で消去する / Example 1: clear the data below the header (row 2), columns A-D＞
'   Dim lastRow As Long
'   Dim rng As Range
'
'   lastRow = 部品_最終行取得(ThisWorkbook, "転記先", 1)     '1列目で最終行を取得 / get the last row by column 1
'   Set rng = 部品_範囲設定_固定(ThisWorkbook, "転記先", 3, 1, lastRow, 4)
'
'   If 部品_範囲消去_値のみ(rng) = False Then
'       MsgBox "消去に失敗しました（シートの保護などを確認してください）"
'       Exit Sub
'   End If
'
'   ＜例2：表の下の但し書き（2行）を除いて消去する / Example 2: exclude a 2-row note below the table＞
'   lastRow = 部品_最終行取得(ThisWorkbook, "帳票", 1)
'   lastRow = lastRow - 2                                    '但し書きの2行を除く / exclude the 2 note rows
'   Set rng = 部品_範囲設定_固定(ThisWorkbook, "帳票", 3, 1, lastRow, 5)
'
'   If 部品_範囲消去_値のみ(rng) = False Then MsgBox "消去に失敗しました"
'
'   ＜例3：開いたファイルの範囲を消去する / Example 3: clear a range of an opened file＞
'   Dim wbDst As Workbook
'
'   If 部品_ファイルを開く("E:\TEST\テンプレート.xlsx") = False Then Exit Sub
'   Set wbDst = ActiveWorkbook                               '開いた直後に控える / keep it right after opening
'
'   Set rng = 部品_範囲設定_固定(wbDst, "帳票", 3, 1, 20, 5)
'   If 部品_範囲消去_値のみ(rng) = False Then MsgBox "消去に失敗しました"
'
'   ※ 範囲が Nothing の場合は、False ではなく、原因を示すエラーで止まる
'      （起点の On Error で受けて、Err.Description を表示する）
'===========================================================

'===========================================================
' ■ラッパー関数（日本語名） / 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 vRng As Range) As Boolean

    '本体処理（英語名）を呼び出し、結果をそのまま返す / Call core function and return its result
    部品_範囲消去_値のみ = f_ClearRange_Contents(vRng)

End Function

'===========================================================
' ■本体処理（英語名） / Core Function
'   ・指定した範囲の、値（入力された内容）だけを消去する
'     → Clears only the values (contents) of the specified range.
'
'   ・消去できた場合：True、実行時にできなかった場合：False を返す
'     → Returns True if cleared and False if it failed at run time.
'===========================================================
Function f_ClearRange_Contents(ByVal vRng As Range) As Boolean

    f_ClearRange_Contents = False

    '---------------------------------------------
    ' ■範囲が設定されているかを確認（Nothing の場合はエラーで止める）
    '   ※ On Error GoTo より前に置く（Err.Raise を False に変えず、呼び出し側へ届けるため）
    '   / Check that the range is set (stop with an error if Nothing);
    '     placed before On Error GoTo so that Err.Raise reaches the caller
    '---------------------------------------------
    If vRng Is Nothing Then
        Err.Raise vbObjectError + 1014, "f_ClearRange_Contents", _
                  "範囲（vRng）が設定されていません（Nothing）。"
    End If

    '---------------------------------------------
    ' ■エラー時は ErrHandler へ（False を返す） / On error, jump to ErrHandler (returns False)
    '---------------------------------------------
    On Error GoTo ErrHandler

    '---------------------------------------------
    ' ■消去 / Clear
    '---------------------------------------------
    vRng.ClearContents

    f_ClearRange_Contents = True
    Exit Function

ErrHandler:
    Debug.Print "f_ClearRange_Contents: " & Err.Number & " " & Err.Description
    f_ClearRange_Contents = False

End Function
