Option Explicit

'===========================================================
' ■部品_代入_セル / AssignCell
'   ・1つのセルの値を、別の1つのセルへ、「＝」で代入する部品（基本の部品）
'     → Assigns the value of one cell to another single cell with "=" (the basic component).
'
'   ・転記元・転記先のブック（ThisWorkbook か ActiveWorkbook か）とシート名、行番号・列番号を、
'     すべて引数で明示して指定する
'     → The source and destination workbook (ThisWorkbook or ActiveWorkbook), sheet name, row and column
'        are all specified explicitly by arguments.
'
'   ・名前に「代入（Assign）」が付く部品は、マッピング表も範囲設定部品も使わない、1つのセルだけの部品である
'     → Components named "代入 (Assign)" work on a single cell and use neither a mapping table nor the
'        range-setting component (Transfer = mapping table, Copy = a range, Assign = one cell).
'
'   ★ この部品は Sub（プロシージャ）ではなく「Function（関数）」で、成功／失敗を Boolean で返す
'     → ★ This component is a Function (not a Sub) that returns success/failure as a Boolean.
'===========================================================

'===========================================================
' ■区分 / Classification
'   ・基礎区分：土台 ／ 用途区分：処理 ／ 操作対象区分：セル
'     → Base: foundation / Purpose: process / Target: cell
'
' ■バージョン / Version
'   ・Version 1.0（2026-10-27）
'===========================================================

'===========================================================
' ■URL（WordPress部品ページ）
'   https://feelcodelab.com/vba_parts/assigncell/
'===========================================================

'===========================================================
' ■前提条件（AI誤動作防止の最重要項目） / Preconditions
'   ★【最重要】この部品は Function（関数）であり、戻り値（Boolean）を返す
'     → 処理できた場合は True、実行時にできなかった場合は False（この場合は、エラーでは止まらない）
'     → 呼び出し側は、必ず戻り値を確認してから後続処理を行い、メッセージも呼び出し側で表示する
'     → ★ [MOST IMPORTANT] This component is a Function that returns a Boolean: True if the assignment
'        succeeded, 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.
'
'   ★【最重要】転記元のブック（vSrcWb）と、転記先のブック（vDstWb）は、必ず引数で指定する（省略できない）
'     → ThisWorkbook ＝ このマクロが入っているブック ／ ActiveWorkbook ＝ いまアクティブなブック
'     → ファイルを開く部品の後は、ActiveWorkbook が、開いたファイルに切り替わる。
'       開いた直後に、ActiveWorkbook を変数へ控えて、その変数を渡す
'     → ★ [MOST IMPORTANT] The source workbook (vSrcWb) and the destination workbook (vDstWb) must always be
'        specified (they cannot be omitted). After the "open file" component runs, ActiveWorkbook switches to
'        the opened file, so keep it in a variable right after opening and pass that variable.
'
'   ・設定の誤りは、False ではなく、原因を示すエラーで止まる（Err.Raise）
'       - ブック（vSrcWb／vDstWb）が Nothing（vbObjectError + 1001：転記元／1002：転記先）
'       - シート名が、指定したブックに存在しない（vbObjectError + 1004：転記元／1005：転記先）
'       - 行番号・列番号が 1 未満（vbObjectError + 1007）、またはシートの上限を超えている（+1009）
'     → Setting mistakes stop with an error naming the cause instead of returning False:
'        a Nothing workbook (+1001 source / +1002 destination), a sheet name that does not exist in the
'        specified workbook (+1004 source / +1005 destination), or a row/column number below 1 (+1007) or
'        over the sheet limit (+1009).
'
'   ・シートは、シート名の文字列で指定する（Worksheet は渡さない）
'     → Sheets are specified by name (not as Worksheet).
'
'   ・False を返すのは、実行時にできなかった場合（保護されたシートへの代入など）
'     → False is returned only when the assignment failed at run time (e.g., a protected sheet).
'
'   ・代入されるのは「値のみ」（書式・数式・入力規則は代入されない）
'     → Only the value is assigned (formats, formulas and validation are not).
'       数式のセルは、計算結果の値が代入される
'       → For a formula cell, its calculated value is assigned.
'
'   ・転記先に既にある値は、確認なしで上書きされる
'     → An existing value in the destination is overwritten without confirmation.
'
'   ・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_OpenFile_ByPath → f_AssignCell
'     （転記先のファイルを開いてから代入する場合。開いた直後に ActiveWorkbook を変数へ控える）
'     → Typical combination: [OpenFile_ByPath] -> [AssignCell]
'        (keep ActiveWorkbook in a variable right after opening).
'===========================================================

'===========================================================
' ■依存関係（シート・表） / Sheet Dependencies
'   ・特になし（マッピング表等は不要）
'     → No sheet-level dependencies (no mapping table etc. required).
'===========================================================

'===========================================================
' ■技術解説 / Technical Notes
'
'   ・「基本（Assign）」の位置づけ
'       → 「転記（Transfer）」はマッピング表、「コピー（Copy）」は範囲（範囲設定部品の Range）を使う。
'          この部品は、そのどちらも使わず、1つのセルを「＝」で代入するだけの、最も基本の部品である。
'       → "Transfer" uses a mapping table and "Copy" uses a range (from the range-setting component); this is
'          the most basic component, assigning one cell with "=" and using neither.
'
'   ・Sub ではなく Function（関数）にして、Boolean を返している理由
'       → 処理に失敗することがある（保護されたシートなど）。呼び出し側が、
'          戻り値で成功／失敗を確認できるようにして、メッセージやエラー処理は、呼び出し側で調整できるようにしている。
'          部品の中では、実行時のエラーを True / False に変えるだけで、メッセージは表示しない。
'       → The assignment can fail (e.g., a protected sheet). The Boolean return value lets the
'          caller check the result, while messages and error handling are left to the caller.
'
'   ・Function の呼び出し方（Sub との違い）
'       → 戻り値を使う場合は、引数を「かっこ」で囲んで呼び出す。
'            If 部品_代入_セル(...) = False Then ...
'       → かっこなしや Call で呼ぶと戻り値が捨てられ、成功／失敗を判定できない。
'       → Wrap the arguments in parentheses to use the return value.
'          Calling without parentheses or with Call discards it, so no check is possible.
'
'   ・ブックを、省略できない引数にしている理由
'       → シート名だけでは、どのブックのシートか決まらず、Worksheets("名前") は、そのときの
'          ActiveWorkbook のシートを指してしまう。ファイルを開くと ActiveWorkbook が切り替わるため、
'          取り違えが起きやすい。ブックを必ず引数で渡す形にすると、呼び出しの行に
'          「どのブックからどのブックへ」が書かれ、読むだけで意図が分かる。
'       → A sheet name alone does not identify the workbook, and Worksheets("name") would refer to the current
'          ActiveWorkbook, which switches when a file is opened. Always passing the workbooks makes the call
'          itself say "from which workbook to which".
'
'   ・シートを、Worksheet ではなく、シート名で受け取る理由
'       → 存在しないシートを Worksheets("名前") で取得すると、部品に入る前に、呼び出し側で
'          「インデックスが有効範囲にありません」のエラーになる。名前で受け取り、部品の中で
'          存在確認を行うことで、どのシートが存在しないのかを示すエラーにできる。
'       → Getting a missing sheet with Worksheets("name") would raise "Subscript out of range" on the caller side
'          before the component runs; receiving the name and checking it inside lets the error name the sheet.
'
'   ・シートの存在確認を、部品の中に直接書いている理由
'       → 土台の部品は、他の部品（シート存在チェック）を参照しない決まりのため。
'          数行が他の土台と重複するが、1つの部品だけをコピーして使えることを優先している。
'       → A foundation component does not reference other components (SheetExists). The few duplicated lines
'          let this one component be copied and used on its own.
'
'   ・行番号・列番号の誤りを、False ではなく Err.Raise で止める理由
'       → 0 や、シートの上限を超える番号は、「実行時にできなかった」ではなく「番号の指定の誤り」である。
'          False で返すと、保護されたシートなどの失敗と区別できず、原因が分かりにくくなる。
'       → A number below 1 or over the sheet limit is a setting mistake, not a run-time failure; returning False
'          would be indistinguishable from failures such as a protected sheet.
'
'   ・確認を 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 checks are placed before it so that Err.Raise reaches the caller.
'
'   ・行番号・列番号で指定する理由
'       → セルの番地の文字列（"B6" など）を直書きせず、他の部品（最終行取得など）の結果を、
'          そのまま使えるようにするため。
'       → It avoids hard-coded address strings and lets the results of other components (e.g., last row) be used.
'
'   ・Offset / Find / Resize / With を禁止する理由
'       → 生成AIが誤って不正な範囲操作を行う可能性が高く、行数可変の処理で誤動作を引き起こしやすいため。
'       → These statements often cause misaligned or ambiguous range operations when generated by AI.
'
'   ・本部品が「土台」である理由
'       → 転記・コピーなど、セルの値を扱う多くの処理の基本となり、
'          しかも他の部品を参照せずに単独で動くため。
'       → It is the basis of many value-handling operations and works on its own
'          without referencing other components.
'===========================================================

'---------------------------------------------
' ■引数（型＋意味） / Arguments
'   vSrcWb        : 転記元のブック（Workbook）※必須（省略できない）
'                   → Source workbook (Workbook); required.
'
'   vSrcSheetName : 転記元のシート名（String）
'                   → Source sheet name (String).
'
'   vSrcRow       : 転記元のセルの行番号（Long）
'                   → Row number of the source cell (Long).
'
'   vSrcCol       : 転記元のセルの列番号（Long）
'                   → Column number of the source cell (Long).
'
'   vDstWb        : 転記先のブック（Workbook）※必須（省略できない）
'                   → Destination workbook (Workbook); required.
'
'   vDstSheetName : 転記先のシート名（String）
'                   → Destination sheet name (String).
'
'   vDstRow       : 転記先のセルの行番号（Long）
'                   → Row number of the destination cell (Long).
'
'   vDstCol       : 転記先のセルの列番号（Long）
'                   → Column number of the destination cell (Long).
'---------------------------------------------

'---------------------------------------------
' ■戻り値（型＋意味） / Return Value
'   Boolean : 代入できた場合は True、実行時にできなかった場合は False
'             → True if the value was assigned, False if it failed at run time.
'---------------------------------------------

'---------------------------------------------
' ■エラー / Errors (Err.Raise)
'   ・vbObjectError + 1001：転記元のブック（vSrcWb）が Nothing
'   ・vbObjectError + 1002：転記先のブック（vDstWb）が Nothing
'   ・vbObjectError + 1004：転記元のシート（vSrcSheetName）が、ブックに存在しない
'   ・vbObjectError + 1005：転記先のシート（vDstSheetName）が、ブックに存在しない
'   ・vbObjectError + 1007：行番号・列番号のどれかが 1 未満
'   ・vbObjectError + 1009：行番号・列番号のどれかが、シートの上限（行数・列数）を超えている
'---------------------------------------------

'===========================================================
' ■禁止事項（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.
'
'   ・転記元・転記先のブックを省略することの禁止（必ず引数で指定する）
'     → Do not omit the source/destination workbooks; always specify them.
'
'   ・Worksheets("名前") で取得したシートを、シート名の代わりに渡すことの禁止（シート名の文字列を渡す）
'     → Do not pass a sheet obtained with Worksheets("name"); pass the sheet name as a string.
'
'   ・セル参照の直書き禁止（Range("A1") など）
'     → Hard-coded cell references are prohibited; use Cells with row/column numbers.
'
'   ・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
'   ★ ブック（ThisWorkbook か ActiveWorkbook か）を明示して、1つのセルを別のセルへ代入する
'   ★ Assign one cell to another with the workbooks specified explicitly
'
'   ＜例1：マクロのファイル（ThisWorkbook）の中で、B6 から A3 へ / Example 1: inside the macro file, B6 to A3＞
'   '転記元：入力シートの B6（6行目・2列目）、転記先：帳票シートの A3（3行目・1列目）
'   If 部品_代入_セル(ThisWorkbook, "入力", 6, 2, ThisWorkbook, "帳票", 3, 1) = False Then
'       MsgBox "代入に失敗しました（シートの保護などを確認してください）"
'   End If
'
'   ＜例2：開いたファイルへ代入する / Example 2: assign into an opened file＞
'   Dim wbDst As Workbook
'
'   If 部品_ファイルを開く("E:\TEST\テンプレート.xlsx") = False Then
'       MsgBox "テンプレートを開けませんでした"
'       Exit Sub
'   End If
'   Set wbDst = ActiveWorkbook                          '開いた直後に控える / keep it right after opening
'
'   '転記元＝マクロのファイル（ThisWorkbook）、転記先＝開いたファイル（wbDst）
'   If 部品_代入_セル(ThisWorkbook, "入力", 6, 2, wbDst, "帳票", 3, 1) = False Then
'       MsgBox "代入に失敗しました"
'   End If
'
'   ※ シート名が存在しない場合や、行番号・列番号の誤りは、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 vSrcWb As Workbook, _
        ByVal vSrcSheetName As String, _
        ByVal vSrcRow As Long, _
        ByVal vSrcCol As Long, _
        ByVal vDstWb As Workbook, _
        ByVal vDstSheetName As String, _
        ByVal vDstRow As Long, _
        ByVal vDstCol As Long) As Boolean

    '本体処理（英語名）を呼び出し、結果をそのまま返す / Call core function and return its result
    部品_代入_セル = f_AssignCell(vSrcWb, vSrcSheetName, vSrcRow, vSrcCol, _
                                  vDstWb, vDstSheetName, vDstRow, vDstCol)

End Function

'===========================================================
' ■本体処理（英語名） / Core Function
'   ・転記元のセルの値を、転記先のセルへ「＝」で代入する
'     → Assigns the value of the source cell to the destination cell with "=".
'
'   ・代入できた場合：True、実行時にできなかった場合：False を返す
'     → Returns True if assigned and False if it failed at run time.
'===========================================================
Function f_AssignCell( _
        ByVal vSrcWb As Workbook, _
        ByVal vSrcSheetName As String, _
        ByVal vSrcRow As Long, _
        ByVal vSrcCol As Long, _
        ByVal vDstWb As Workbook, _
        ByVal vDstSheetName As String, _
        ByVal vDstRow As Long, _
        ByVal vDstCol As Long) As Boolean

    Dim wsSrc As Worksheet
    Dim wsDst As Worksheet

    f_AssignCell = False

    '---------------------------------------------
    ' ■ブックが設定されているかを確認（Nothing の場合はエラーで止める）
    '   / Check that the workbooks are set (stop with an error if Nothing)
    '---------------------------------------------
    If vSrcWb Is Nothing Then
        Err.Raise vbObjectError + 1001, "f_AssignCell", _
                  "転記元のブック（vSrcWb）が設定されていません（Nothing）。"
    End If

    If vDstWb Is Nothing Then
        Err.Raise vbObjectError + 1002, "f_AssignCell", _
                  "転記先のブック（vDstWb）が設定されていません（Nothing）。"
    End If

    '---------------------------------------------
    ' ■シートの存在を確認（存在しない場合は、シート名とブック名を示すエラーで止める）
    '   ※ On Error GoTo ErrHandler より前に置く（Err.Raise を False に変えず、呼び出し側へ届けるため）
    '   / Check that the sheets exist (stop with an error naming the sheet and workbook);
    '     placed before On Error GoTo ErrHandler so that Err.Raise reaches the caller
    '---------------------------------------------
    On Error Resume Next
    Set wsSrc = vSrcWb.Worksheets(vSrcSheetName)
    Set wsDst = vDstWb.Worksheets(vDstSheetName)
    On Error GoTo 0

    If wsSrc Is Nothing Then
        Err.Raise vbObjectError + 1004, "f_AssignCell", _
                  "転記元シート「" & vSrcSheetName & "」が、ブック「" & vSrcWb.Name & "」に存在しません。"
    End If

    If wsDst Is Nothing Then
        Err.Raise vbObjectError + 1005, "f_AssignCell", _
                  "転記先シート「" & vDstSheetName & "」が、ブック「" & vDstWb.Name & "」に存在しません。"
    End If

    '---------------------------------------------
    ' ■行番号・列番号を確認（誤りは、原因を示すエラーで止める）
    '   / Check the row and column numbers (stop with an error naming the cause)
    '---------------------------------------------
    If vSrcRow < 1 Or vSrcCol < 1 Or vDstRow < 1 Or vDstCol < 1 Then
        Err.Raise vbObjectError + 1007, "f_AssignCell", _
                  "行番号・列番号は 1 以上を指定してください" & _
                  "（転記元：" & vSrcRow & "行・" & vSrcCol & "列、転記先：" & vDstRow & "行・" & vDstCol & "列）。"
    End If

    If vSrcRow > wsSrc.Rows.Count Or vSrcCol > wsSrc.Columns.Count _
            Or vDstRow > wsDst.Rows.Count Or vDstCol > wsDst.Columns.Count Then
        Err.Raise vbObjectError + 1009, "f_AssignCell", _
                  "行番号・列番号が、シートの上限（" & wsSrc.Rows.Count & "行・" & wsSrc.Columns.Count & "列）を超えています" & _
                  "（転記元：" & vSrcRow & "行・" & vSrcCol & "列、転記先：" & vDstRow & "行・" & vDstCol & "列）。"
    End If

    '---------------------------------------------
    ' ■エラー時は ErrHandler へ（False を返す） / On error, jump to ErrHandler (returns False)
    '---------------------------------------------
    On Error GoTo ErrHandler

    '---------------------------------------------
    ' ■「＝」で値を代入 / Assign the value with "="
    '---------------------------------------------
    wsDst.Cells(vDstRow, vDstCol).Value = wsSrc.Cells(vSrcRow, vSrcCol).Value

    f_AssignCell = True
    Exit Function

ErrHandler:
    Debug.Print "f_AssignCell: " & Err.Number & " " & Err.Description
    f_AssignCell = False

End Function
