Attribute VB_Name = "UtilforInfoSheet"
'============================================================
'
'  QSET User Defined Functions (UDF) Library
'
'  ¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡
'  [°ª Á¶È¸]
'    GV(col_name)                  - Get Value (IFCGUID ±â¹Ý ÅëÇÕ °ª Á¶È¸)
'
'  [°ÅÇªÁý - FormWork]
'    FWS(step_no, [prev_length])   - FormWork Specification (´Üº° ³ôÀÌ ±¸°£ ½ºÆå)
'    FWH(step_no, [prev_length])   - FormWork Height (´Üº° ³ôÀÌ)
'    FWAE(step_no, [prev_length])  - FormWork Area Exterior (¿ÜÃø ´Üº° ¸éÀû)
'    FWAI(step_no, [prev_length])  - FormWork Area Interior (³»Ãø ´Üº° ¸éÀû)
'    FWA(step_no, [prev_length])   - FormWork Area (¿ÜÃø+³»Ãø ´Üº° ÇÕ»ê ¸éÀû)
'    FWD(se_flag)                  - FormWork Deduction (°ÅÇªÁý °øÁ¦, ´Ü¸éÀû)
'
'  [µµÀå - Paint]
'    PTE()                         - PainT Exterior (¿ÜÃø µµÀå ¸éÀû)
'    PTI()                         - PainT Interior (³»Ãø µµÀå ¸éÀû)
'    PTA()                         - PainT Area (¿ÜÃø+³»Ãø µµÀå ÇÕ»ê ¸éÀû)
'
'  ¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡
'  [prev_length ¸Å°³º¯¼ö]
'    ÀÌÀü °´Ã¼ÀÇ ´©Àû ³ôÀÌ. »ý·« ½Ã 0À¸·Î Ã³¸® (±âÁ¸ µ¿ÀÛ°ú µ¿ÀÏ)
'    step_no´Â ÇöÀç °´Ã¼ ±âÁØÀÇ »ó´ë ´Ü¹øÈ£ÀÌ¸ç,
'    prev_length¸¦ Æ÷ÇÔÇÑ ÇÕ»ê ³ôÀÌ·Î Àý´ë ´ÜÀ» »êÁ¤ÇÕ´Ï´Ù.
'
'    ¿¹) °´Ã¼ ±æÀÌ=5m, FWS(1, 12)
'        ÇÕ»ê=17m, °´Ã¼ ±¸°£=12~17m
'        °´Ã¼ÀÇ 1¹øÂ° ´Ü = Àý´ë 3´Ü(10~13m) ¡æ "10mÃÊ°ú~13mÀÌÇÏ"
'        FWH(1, 12) = 1m (3´Ü ÀÜ¿©)
'
'  [º¯´Ü¸é(Tapered) Ã³¸®]
'    MEMBER ½ÃÆ®ÀÇ Tapered ¿­ÀÌ ºñ¾îÀÖÁö ¾ÊÀ¸¸é º¯´Ü¸éÀ¸·Î ÆÇÁ¤.
'    º¯´Ü¸éÀÎ °æ¿ì:
'      ÃÑ Ãø¸éÀû = SurfaceArea - FaceArea(S) - FaceArea(E)
'      FWAE/FWAI/FWA: µÑ·¹±æÀÌ ¼±Çüº¸°£ + »ç´Ù¸®²Ã ¸éÀû ±â¹Ý °¡Áß ¹èºÐ
'      PTE/PTI/PTA: µÑ·¹ÇÕ(S+E) ºñÀ²·Î ¿ÜÃø/³»Ãø ¹èºÐ
'    µî´Ü¸éÀÎ °æ¿ì ±âÁ¸ ¹æ½Ä(FWH ¡¿ Perimeter) À¯Áö.
'  ¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡
'
'============================================================
'************************************************************
'
'  0. ³»ºÎ À¯Æ¿¸®Æ¼ ÇÔ¼ö (Private)
'
'************************************************************
'============================================================
' GetAbsoluteStepForObject - ³»ºÎ À¯Æ¿¸®Æ¼ (Private)
'
'   ÇöÀç °´Ã¼ÀÇ »ó´ë ´Ü¹øÈ£(obj_step_no)¸¦
'   Àý´ë ´Ü¹øÈ£(abs_step)·Î º¯È¯ÇÏ°í,
'   ÇØ´ç ´Ü¿¡¼­ ÇöÀç °´Ã¼°¡ Â÷ÁöÇÏ´Â ³ôÀÌ¸¦ ¹ÝÈ¯
'============================================================
Private Function GetAbsoluteStepForObject(totalLength As Double, _
                                           obj_step_no As Long, _
                                           prev_length As Double, _
                                           ByRef abs_step As Long, _
                                           ByRef stepHeight As Double) As Boolean
    Dim combinedLength As Double
    Dim objStart As Double
    Dim objEnd As Double
    Dim sStart As Double
    Dim sEnd As Double
    Dim oStart As Double
    Dim oEnd As Double
    Dim count As Long
    Dim s As Long
    
    GetAbsoluteStepForObject = False
    abs_step = 0
    stepHeight = 0
    
    If totalLength <= 0 Or obj_step_no < 1 Then Exit Function
    If prev_length < 0 Then prev_length = 0
    
    combinedLength = prev_length + totalLength
    objStart = prev_length
    objEnd = combinedLength
    
    count = 0
    s = 1
    
    Do
        If s = 1 Then
            sStart = 0
            sEnd = 7
        Else
            sStart = 7 + CDbl(s - 2) * 3
            sEnd = sStart + 3
        End If
        
        If sStart >= combinedLength Then Exit Do
        If sEnd > combinedLength Then sEnd = combinedLength
        
        oStart = sStart
        If objStart > oStart Then oStart = objStart
        oEnd = sEnd
        If objEnd < oEnd Then oEnd = objEnd
        
        If oEnd > oStart Then
            count = count + 1
            
            If count = obj_step_no Then
                abs_step = s
                stepHeight = oEnd - oStart
                GetAbsoluteStepForObject = True
                Exit Function
            End If
        End If
        
        s = s + 1
    Loop
    
    GetAbsoluteStepForObject = False
End Function

'============================================================
' GetStepHeight - ³»ºÎ À¯Æ¿¸®Æ¼ (Private)
'
'   ÇöÀç °´Ã¼ ±âÁØ »ó´ë ´Ü¹øÈ£·Î ³ôÀÌ¸¦ ¹ÝÈ¯
'   ¹ÝÈ¯°ª: ÇØ´ç ´ÜÀÇ ³ôÀÌ (Double), ÇØ´ç ´Ü ¾øÀ¸¸é -1
'============================================================
Private Function GetStepHeight(totalLength As Double, obj_step_no As Long, _
                               Optional prev_length As Double = 0) As Double
    Dim abs_step As Long
    Dim sHeight As Double
    
    If GetAbsoluteStepForObject(totalLength, obj_step_no, prev_length, abs_step, sHeight) Then
        GetStepHeight = sHeight
    Else
        GetStepHeight = -1
    End If
End Function

'============================================================
' GetStepSpec - ³»ºÎ À¯Æ¿¸®Æ¼ (Private)
'
'   Àý´ë ´Ü¹øÈ£·ÎºÎÅÍ ½ºÆå ¹®ÀÚ¿­À» ¹ÝÈ¯
'   1´Ü ¡æ "0~7mÀÌÇÏ"
'   n´Ü ¡æ "(7+(n-2)*3)mÃÊ°ú~(7+(n-1)*3)mÀÌÇÏ"
'============================================================
Private Function GetStepSpec(abs_step As Long) As String
    Dim sStart As Double
    Dim sEnd As Double
    
    If abs_step < 1 Then
        GetStepSpec = ""
        Exit Function
    End If
    
    If abs_step = 1 Then
        GetStepSpec = "0~7mÀÌÇÏ"
    Else
        sStart = 7 + CDbl(abs_step - 2) * 3
        sEnd = sStart + 3
        GetStepSpec = CStr(CLng(sStart)) & "mÃÊ°ú~" & CStr(CLng(sEnd)) & "mÀÌÇÏ"
    End If
End Function

'============================================================
' ParsePrevLength - ³»ºÎ À¯Æ¿¸®Æ¼ (Private)
'
'   Optional prev_length ¸Å°³º¯¼ö¸¦ ¾ÈÀüÇÏ°Ô Double·Î º¯È¯
'   Missing / Empty / ºó¹®ÀÚ¿­ ¡æ 0
'============================================================
Private Function ParsePrevLength(prev_length As Variant) As Double
    If IsMissing(prev_length) Then
        ParsePrevLength = 0
    ElseIf IsEmpty(prev_length) Then
        ParsePrevLength = 0
    ElseIf Len(Trim(CStr(prev_length))) = 0 Then
        ParsePrevLength = 0
    Else
        ParsePrevLength = CDbl(prev_length)
    End If
End Function

'============================================================
' IsTapered - ³»ºÎ À¯Æ¿¸®Æ¼ (Private)
'
'   MEMBER ½ÃÆ®¿¡¼­ ÇØ´ç ÇàÀÇ Tapered ¿­ °ªÀ» È®ÀÎ
'   ºñ¾îÀÖÁö ¾ÊÀ¸¸é True (º¯´Ü¸é)
'============================================================
Private Function IsTapered(ws As Worksheet, rowMatch As Long) As Boolean
    Dim colTapered As Variant
    Dim val As Variant
    
    colTapered = Application.Match("Tapered", ws.Rows(1), 0)
    
    If IsError(colTapered) Then
        IsTapered = False
        Exit Function
    End If
    
    val = ws.Cells(rowMatch, colTapered).Value
    
    If IsEmpty(val) Or Len(Trim(CStr(val))) = 0 Then
        IsTapered = False
    Else
        IsTapered = True
    End If
End Function

'============================================================
' GetTaperedStepArea - ³»ºÎ À¯Æ¿¸®Æ¼ (Private)
'
'   º¯´Ü¸é ºÎÀçÀÇ ´Üº° ¿ÜÃø/³»Ãø/ÇÕ»ê ¸éÀûÀ» °è»ê
'   µÑ·¹±æÀÌ ¼±Çü º¸°£ + »ç´Ù¸®²Ã ¸éÀû ±â¹Ý °¡Áß ¹èºÐ
'
'   ¸Å°³º¯¼ö:
'     ws           - MEMBER ½ÃÆ®
'     rowMatch     - MEMBER ½ÃÆ®¿¡¼­ ¸ÅÄªµÈ Çà
'     totalLength  - ÇöÀç °´Ã¼ Length
'     stepH        - ÇØ´ç ´Ü¿¡¼­ ÇöÀç °´Ã¼ÀÇ ±â¿© ³ôÀÌ (FWH)
'     objStart     - ÇöÀç °´Ã¼ÀÇ ½ÃÀÛ ³ôÀÌ (= prev_length)
'     stepStart    - ÇØ´ç ´Ü¿¡¼­ ÇöÀç °´Ã¼ÀÇ ½ÇÁ¦ ½ÃÀÛ ³ôÀÌ (Àý´ë ±âÁØ)
'     mode         - "EXT" / "INT" / "ALL"
'
'   °è»ê ·ÎÁ÷:
'     1. ÃÑ Ãø¸éÀû = SurfaceArea - FaceArea(S) - FaceArea(E)
'     2. ÀüÃ¼ »ç´Ù¸®²Ã·Î ¿ÜÃø/³»Ãø Ãø¸éÀû ºÐ¸®
'     3. µÑ·¹±æÀÌ ¼±Çü º¸°£À¸·Î ´Ü ½ÃÀÛ/³¡ µÑ·¹ °è»ê
'     4. »ç´Ù¸®²Ã ¸éÀû = (½ÃÀÛµÑ·¹ + ³¡µÑ·¹) / 2 ¡¿ ´Ü³ôÀÌ
'     5. °¡Áß ºñÀ²·Î ½ÇÁ¦ Ãø¸éÀû ¹èºÐ
'============================================================
Private Function GetTaperedStepArea(ws As Worksheet, rowMatch As Long, _
                                     totalLength As Double, stepH As Double, _
                                     objStart As Double, stepStart As Double, _
                                     mode As String) As Double
    Dim colSA As Variant
    Dim colFAS As Variant
    Dim colFAE As Variant
    Dim colPExtS As Variant
    Dim colPExtE As Variant
    Dim colPIntS As Variant
    Dim colPIntE As Variant
    
    Dim surfaceArea As Double
    Dim faceAreaS As Double
    Dim faceAreaE As Double
    Dim totalLateral As Double
    
    Dim periExtS As Double
    Dim periExtE As Double
    Dim periIntS As Double
    Dim periIntE As Double
    
    Dim pExtAtStart As Double
    Dim pExtAtEnd As Double
    Dim pIntAtStart As Double
    Dim pIntAtEnd As Double
    Dim trapExt As Double
    Dim trapInt As Double
    Dim trapAll As Double
    
    Dim totalTrapExt As Double
    Dim totalTrapInt As Double
    Dim totalTrapAll As Double
    
    Dim lateralExt As Double
    Dim lateralInt As Double
    
    Dim relStart As Double
    Dim relEnd As Double
    
    ' ¿­ °Ë»ö
    colSA = Application.Match("SurfaceArea", ws.Rows(1), 0)
    colFAS = Application.Match("FaceArea(S)", ws.Rows(1), 0)
    colFAE = Application.Match("FaceArea(E)", ws.Rows(1), 0)
    colPExtS = Application.Match("PerimeterExt(S)", ws.Rows(1), 0)
    colPExtE = Application.Match("PerimeterExt(E)", ws.Rows(1), 0)
    colPIntS = Application.Match("PerimeterInt(S)", ws.Rows(1), 0)
    colPIntE = Application.Match("PerimeterInt(E)", ws.Rows(1), 0)
    
    If IsError(colSA) Or IsError(colFAS) Or IsError(colFAE) Or _
       IsError(colPExtS) Or IsError(colPExtE) Or _
       IsError(colPIntS) Or IsError(colPIntE) Then
        GetTaperedStepArea = -1
        Exit Function
    End If
    
    ' °ª ÀÐ±â
    surfaceArea = ws.Cells(rowMatch, colSA).Value
    faceAreaS = ws.Cells(rowMatch, colFAS).Value
    faceAreaE = ws.Cells(rowMatch, colFAE).Value
    periExtS = ws.Cells(rowMatch, colPExtS).Value
    periExtE = ws.Cells(rowMatch, colPExtE).Value
    periIntS = ws.Cells(rowMatch, colPIntS).Value
    periIntE = ws.Cells(rowMatch, colPIntE).Value
    
    ' Step 1: ÃÑ Ãø¸éÀû
    totalLateral = surfaceArea - faceAreaS - faceAreaE
    If totalLateral <= 0 Then
        GetTaperedStepArea = 0
        Exit Function
    End If
    
    If totalLength <= 0 Then
        GetTaperedStepArea = 0
        Exit Function
    End If
    
    ' Step 2: ÀüÃ¼ »ç´Ù¸®²Ã·Î ¿ÜÃø/³»Ãø Ãø¸éÀû ºÐ¸®
    totalTrapExt = (periExtS + periExtE) / 2 * totalLength
    totalTrapInt = (periIntS + periIntE) / 2 * totalLength
    totalTrapAll = totalTrapExt + totalTrapInt
    
    If totalTrapAll <= 0 Then
        GetTaperedStepArea = 0
        Exit Function
    End If
    
    lateralExt = totalLateral * (totalTrapExt / totalTrapAll)
    lateralInt = totalLateral * (totalTrapInt / totalTrapAll)
    
    ' Step 3: ÇØ´ç ´ÜÀÇ »ç´Ù¸®²Ã ¸éÀû °è»ê
    '   °´Ã¼ ³» »ó´ë À§Ä¡ ±âÁØÀ¸·Î µÑ·¹ ¼±Çü º¸°£
    relStart = stepStart - objStart
    relEnd = relStart + stepH
    
    pExtAtStart = periExtS + (periExtE - periExtS) * (relStart / totalLength)
    pExtAtEnd = periExtS + (periExtE - periExtS) * (relEnd / totalLength)
    pIntAtStart = periIntS + (periIntE - periIntS) * (relStart / totalLength)
    pIntAtEnd = periIntS + (periIntE - periIntS) * (relEnd / totalLength)
    
    trapExt = (pExtAtStart + pExtAtEnd) / 2 * stepH
    trapInt = (pIntAtStart + pIntAtEnd) / 2 * stepH
    trapAll = trapExt + trapInt
    
    ' Step 4: °¡Áß ¹èºÐ
    Select Case UCase(mode)
        Case "EXT"
            If totalTrapExt <= 0 Then
                GetTaperedStepArea = 0
            Else
                GetTaperedStepArea = lateralExt * (trapExt / totalTrapExt)
            End If
        Case "INT"
            If totalTrapInt <= 0 Then
                GetTaperedStepArea = 0
            Else
                GetTaperedStepArea = lateralInt * (trapInt / totalTrapInt)
            End If
        Case "ALL"
            If totalTrapAll <= 0 Then
                GetTaperedStepArea = 0
            Else
                GetTaperedStepArea = totalLateral * (trapAll / totalTrapAll)
            End If
        Case Else
            GetTaperedStepArea = -1
    End Select
End Function

'************************************************************
'
'  1. °ª Á¶È¸ ÇÔ¼ö
'
'************************************************************
'============================================================
' GV - Get Value (IFCGUID ±â¹Ý ÅëÇÕ °ª Á¶È¸ ÇÔ¼ö)
'
' »ç¿ë¹ý: =GV("Length")
'         =GV("Weight")
'         =GV("Material")
'
' µ¿ÀÛ:
'   1. È£ÃâµÈ ¼¿ÀÇ °°Àº Çà E¿­¿¡¼­ IFCGUID¸¦ °¡Á®¿È
'   2. MEMBER/TENDON/STIFFENER/BOLT/LAYOUT/ETC ½ÃÆ®¸¦ ¼øÂ÷ °Ë»ö
'   3. IFCGUID°¡ ÀÏÄ¡ÇÏ´Â ÇàÀ» Ã£À¸¸é ÇØ´ç ¿­ÀÇ °ªÀ» ¹ÝÈ¯
'============================================================
Function GV(col_name As String) As Variant
    Dim ws As Worksheet
    Dim myGUID As String
    Dim rowMatch As Variant
    Dim colMatch As Variant
    Dim sheetNames As Variant
    Dim i As Long
    
    On Error GoTo ErrHandler
    
    sheetNames = Array("MEMBER", "TENDON", "STIFFENER", "BOLT", "LAYOUT", "ETC")
    
    myGUID = Application.Caller.Worksheet.Cells(Application.Caller.Row, 5).Value
    
    If Len(Trim(myGUID)) = 0 Then
        GV = "[NO GUID]"
        Exit Function
    End If
    
    For i = LBound(sheetNames) To UBound(sheetNames)
        Set ws = Nothing
        On Error Resume Next
        Set ws = ThisWorkbook.Worksheets(sheetNames(i))
        On Error GoTo ErrHandler
        
        If Not ws Is Nothing Then
            rowMatch = Application.Match(myGUID, ws.Columns("E"), 0)
            
            If Not IsError(rowMatch) Then
                colMatch = Application.Match(col_name, ws.Rows(1), 0)
                
                If IsError(colMatch) Then
                    GV = "[NO COLUMN: " & col_name & "]"
                    Exit Function
                End If
                
                Dim result As Variant
                result = ws.Cells(rowMatch, colMatch).Value
                If IsEmpty(result) Or Len(Trim(CStr(result))) = 0 Then
                    GV = ""
                Else
                    GV = result
                End If
                Exit Function
            End If
        End If
    Next i
    
    GV = "[NO MATCH]"
    Exit Function
    
ErrHandler:
    GV = "[ERROR]"
End Function

'************************************************************
'
'  2. °ÅÇªÁý ÇÔ¼ö (FormWork)
'
'************************************************************
'============================================================
' FWS - °ÅÇªÁý ´Üº° ½ºÆå (FormWork Specification)
'
' »ç¿ë¹ý: =FWS(1)       ¡æ ÇöÀç °´Ã¼ 1¹øÂ° ´ÜÀÇ ³ôÀÌ ±¸°£
'         =FWS(1, 12)   ¡æ ÀÌÀü °´Ã¼ 12m Æ÷ÇÔ, ÇöÀç °´Ã¼ 1¹øÂ° ´ÜÀÇ ³ôÀÌ ±¸°£
'         =FWS(1, 0)    ¡æ =FWS(1)°ú µ¿ÀÏ
'
' ¹ÝÈ¯°ª ¿¹½Ã:
'   "0~7mÀÌÇÏ", "7mÃÊ°ú~10mÀÌÇÏ", "10mÃÊ°ú~13mÀÌÇÏ", ...
'============================================================
Function FWS(step_no As Long, Optional prev_length As Variant) As Variant
    Dim ws As Worksheet
    Dim myGUID As String
    Dim rowMatch As Variant
    Dim colMatch As Variant
    Dim totalLength As Double
    Dim prevLen As Double
    Dim abs_step As Long
    Dim sHeight As Double
    
    On Error GoTo ErrHandler
    
    If step_no < 1 Then
        FWS = "[INVALID STEP]"
        Exit Function
    End If
    
    prevLen = ParsePrevLength(prev_length)
    
    Set ws = ThisWorkbook.Worksheets("MEMBER")
    
    myGUID = Application.Caller.Worksheet.Cells(Application.Caller.Row, 5).Value
    
    If Len(Trim(myGUID)) = 0 Then
        FWS = "[NO GUID]"
        Exit Function
    End If
    
    rowMatch = Application.Match(myGUID, ws.Columns("E"), 0)
    If IsError(rowMatch) Then
        FWS = "[NO MATCH]"
        Exit Function
    End If
    
    colMatch = Application.Match("Length", ws.Rows(1), 0)
    If IsError(colMatch) Then
        FWS = "[NO COLUMN: Length]"
        Exit Function
    End If
    
    totalLength = ws.Cells(rowMatch, colMatch).Value
    
    If GetAbsoluteStepForObject(totalLength, step_no, prevLen, abs_step, sHeight) Then
        FWS = GetStepSpec(abs_step)
    Else
        FWS = ""
    End If
    Exit Function
    
ErrHandler:
    FWS = "[ERROR]"
End Function

'============================================================
' FWH - °ÅÇªÁý ´Üº° ³ôÀÌ (FormWork Height)
'
' »ç¿ë¹ý: =FWH(1)       ¡æ 1´Ü ³ôÀÌ (ÀÌÀü °´Ã¼ ¾øÀ½)
'         =FWH(2, 8)    ¡æ ÀÌÀü °´Ã¼ 8m Æ÷ÇÔ, ÇöÀç °´Ã¼ 2¹øÂ° ´Ü ³ôÀÌ
'============================================================
Function FWH(step_no As Long, Optional prev_length As Variant) As Variant
    Dim ws As Worksheet
    Dim myGUID As String
    Dim rowMatch As Variant
    Dim colMatch As Variant
    Dim totalLength As Double
    Dim prevLen As Double
    
    On Error GoTo ErrHandler
    
    If step_no < 1 Then
        FWH = "[INVALID STEP]"
        Exit Function
    End If
    
    prevLen = ParsePrevLength(prev_length)
    
    Set ws = ThisWorkbook.Worksheets("MEMBER")
    
    myGUID = Application.Caller.Worksheet.Cells(Application.Caller.Row, 5).Value
    
    If Len(Trim(myGUID)) = 0 Then
        FWH = "[NO GUID]"
        Exit Function
    End If
    
    rowMatch = Application.Match(myGUID, ws.Columns("E"), 0)
    If IsError(rowMatch) Then
        FWH = "[NO MATCH]"
        Exit Function
    End If
    
    colMatch = Application.Match("Length", ws.Rows(1), 0)
    If IsError(colMatch) Then
        FWH = "[NO COLUMN: Length]"
        Exit Function
    End If
    
    totalLength = ws.Cells(rowMatch, colMatch).Value
    
    Dim stepH As Double
    stepH = GetStepHeight(totalLength, step_no, prevLen)
    
    If stepH < 0 Then
        FWH = ""
    Else
        FWH = stepH
    End If
    Exit Function
    
ErrHandler:
    FWH = "[ERROR]"
End Function

'============================================================
' FWAE - °ÅÇªÁý ¿ÜÃø ´Üº° ¸éÀû (FormWork Area Exterior)
'
' »ç¿ë¹ý: =FWAE(1)       ¡æ 1´Ü ¿ÜÃø ¸éÀû
'         =FWAE(2, 8)    ¡æ ÀÌÀü °´Ã¼ 8m Æ÷ÇÔ, ÇöÀç °´Ã¼ 2¹øÂ° ´Ü ¿ÜÃø ¸éÀû
'
' µî´Ü¸é: FWH(n, prev) ¡¿ PerimeterExt(S)
' º¯´Ü¸é: µÑ·¹ ¼±Çüº¸°£ »ç´Ù¸®²Ã ¸éÀû ±â¹Ý °¡Áß ¹èºÐ
'============================================================
Function FWAE(step_no As Long, Optional prev_length As Variant) As Variant
    Dim ws As Worksheet
    Dim myGUID As String
    Dim rowMatch As Variant
    Dim colLen As Variant
    Dim colPeri As Variant
    Dim totalLength As Double
    Dim perimeter As Double
    Dim stepH As Double
    Dim prevLen As Double
    Dim abs_step As Long
    
    On Error GoTo ErrHandler
    
    If step_no < 1 Then
        FWAE = "[INVALID STEP]"
        Exit Function
    End If
    
    prevLen = ParsePrevLength(prev_length)
    
    Set ws = ThisWorkbook.Worksheets("MEMBER")
    
    myGUID = Application.Caller.Worksheet.Cells(Application.Caller.Row, 5).Value
    
    If Len(Trim(myGUID)) = 0 Then
        FWAE = "[NO GUID]"
        Exit Function
    End If
    
    rowMatch = Application.Match(myGUID, ws.Columns("E"), 0)
    If IsError(rowMatch) Then
        FWAE = "[NO MATCH]"
        Exit Function
    End If
    
    colLen = Application.Match("Length", ws.Rows(1), 0)
    If IsError(colLen) Then
        FWAE = "[NO COLUMN: Length]"
        Exit Function
    End If
    
    totalLength = ws.Cells(rowMatch, colLen).Value
    
    If Not GetAbsoluteStepForObject(totalLength, step_no, prevLen, abs_step, stepH) Then
        FWAE = ""
        Exit Function
    End If
    
    If IsTapered(ws, CLng(rowMatch)) Then
        Dim absStepStart As Double
        If abs_step = 1 Then
            absStepStart = 0
        Else
            absStepStart = 7 + CDbl(abs_step - 2) * 3
        End If
        
        Dim actualStart As Double
        actualStart = absStepStart
        If prevLen > actualStart Then actualStart = prevLen
        
        Dim areaExt As Double
        areaExt = GetTaperedStepArea(ws, CLng(rowMatch), totalLength, stepH, prevLen, actualStart, "EXT")
        If areaExt < 0 Then
            FWAE = "[ERROR: TAPERED]"
        Else
            FWAE = areaExt
        End If
    Else
        colPeri = Application.Match("PerimeterExt(S)", ws.Rows(1), 0)
        If IsError(colPeri) Then
            FWAE = "[NO COLUMN: PerimeterExt(S)]"
            Exit Function
        End If
        perimeter = ws.Cells(rowMatch, colPeri).Value
        FWAE = stepH * perimeter
    End If
    Exit Function
    
ErrHandler:
    FWAE = "[ERROR]"
End Function

'============================================================
' FWAI - °ÅÇªÁý ³»Ãø ´Üº° ¸éÀû (FormWork Area Interior)
'
' »ç¿ë¹ý: =FWAI(1)       ¡æ 1´Ü ³»Ãø ¸éÀû
'         =FWAI(2, 8)    ¡æ ÀÌÀü °´Ã¼ 8m Æ÷ÇÔ, ÇöÀç °´Ã¼ 2¹øÂ° ´Ü ³»Ãø ¸éÀû
'
' µî´Ü¸é: FWH(n, prev) ¡¿ PerimeterInt(S)
' º¯´Ü¸é: µÑ·¹ ¼±Çüº¸°£ »ç´Ù¸®²Ã ¸éÀû ±â¹Ý °¡Áß ¹èºÐ
'============================================================
Function FWAI(step_no As Long, Optional prev_length As Variant) As Variant
    Dim ws As Worksheet
    Dim myGUID As String
    Dim rowMatch As Variant
    Dim colLen As Variant
    Dim colPeri As Variant
    Dim totalLength As Double
    Dim perimeter As Double
    Dim stepH As Double
    Dim prevLen As Double
    Dim abs_step As Long
    
    On Error GoTo ErrHandler
    
    If step_no < 1 Then
        FWAI = "[INVALID STEP]"
        Exit Function
    End If
    
    prevLen = ParsePrevLength(prev_length)
    
    Set ws = ThisWorkbook.Worksheets("MEMBER")
    
    myGUID = Application.Caller.Worksheet.Cells(Application.Caller.Row, 5).Value
    
    If Len(Trim(myGUID)) = 0 Then
        FWAI = "[NO GUID]"
        Exit Function
    End If
    
    rowMatch = Application.Match(myGUID, ws.Columns("E"), 0)
    If IsError(rowMatch) Then
        FWAI = "[NO MATCH]"
        Exit Function
    End If
    
    colLen = Application.Match("Length", ws.Rows(1), 0)
    If IsError(colLen) Then
        FWAI = "[NO COLUMN: Length]"
        Exit Function
    End If
    
    totalLength = ws.Cells(rowMatch, colLen).Value
    
    If Not GetAbsoluteStepForObject(totalLength, step_no, prevLen, abs_step, stepH) Then
        FWAI = ""
        Exit Function
    End If
    
    If IsTapered(ws, CLng(rowMatch)) Then
        Dim absStepStart As Double
        If abs_step = 1 Then
            absStepStart = 0
        Else
            absStepStart = 7 + CDbl(abs_step - 2) * 3
        End If
        
        Dim actualStart As Double
        actualStart = absStepStart
        If prevLen > actualStart Then actualStart = prevLen
        
        Dim areaInt As Double
        areaInt = GetTaperedStepArea(ws, CLng(rowMatch), totalLength, stepH, prevLen, actualStart, "INT")
        If areaInt < 0 Then
            FWAI = "[ERROR: TAPERED]"
        Else
            FWAI = areaInt
        End If
    Else
        colPeri = Application.Match("PerimeterInt(S)", ws.Rows(1), 0)
        If IsError(colPeri) Then
            FWAI = "[NO COLUMN: PerimeterInt(S)]"
            Exit Function
        End If
        perimeter = ws.Cells(rowMatch, colPeri).Value
        FWAI = stepH * perimeter
    End If
    Exit Function
    
ErrHandler:
    FWAI = "[ERROR]"
End Function

'============================================================
' FWA - °ÅÇªÁý ´Üº° ÇÕ»ê ¸éÀû (FormWork Area)
'
' »ç¿ë¹ý: =FWA(1)       ¡æ 1´Ü ¿Ü+³» ¸éÀû
'         =FWA(2, 8)    ¡æ ÀÌÀü °´Ã¼ 8m Æ÷ÇÔ, ÇöÀç °´Ã¼ 2¹øÂ° ´Ü ¿Ü+³» ¸éÀû
'
' µî´Ü¸é: FWH(n, prev) ¡¿ (PerimeterExt(S) + PerimeterInt(S))
' º¯´Ü¸é: µÑ·¹ ¼±Çüº¸°£ »ç´Ù¸®²Ã ¸éÀû ±â¹Ý °¡Áß ¹èºÐ
'
' ¡Ø °ÅÇªÁý °øÁ¦(FWD)´Â Æ÷ÇÔµÇÁö ¾ÊÀ½. º°µµ Â÷°¨ ÇÊ¿ä.
'============================================================
Function FWA(step_no As Long, Optional prev_length As Variant) As Variant
    Dim ws As Worksheet
    Dim myGUID As String
    Dim rowMatch As Variant
    Dim colLen As Variant
    Dim colPeriExt As Variant
    Dim colPeriInt As Variant
    Dim totalLength As Double
    Dim periExt As Double
    Dim periInt As Double
    Dim stepH As Double
    Dim prevLen As Double
    Dim abs_step As Long
    
    On Error GoTo ErrHandler
    
    If step_no < 1 Then
        FWA = "[INVALID STEP]"
        Exit Function
    End If
    
    prevLen = ParsePrevLength(prev_length)
    
    Set ws = ThisWorkbook.Worksheets("MEMBER")
    
    myGUID = Application.Caller.Worksheet.Cells(Application.Caller.Row, 5).Value
    
    If Len(Trim(myGUID)) = 0 Then
        FWA = "[NO GUID]"
        Exit Function
    End If
    
    rowMatch = Application.Match(myGUID, ws.Columns("E"), 0)
    If IsError(rowMatch) Then
        FWA = "[NO MATCH]"
        Exit Function
    End If
    
    colLen = Application.Match("Length", ws.Rows(1), 0)
    If IsError(colLen) Then
        FWA = "[NO COLUMN: Length]"
        Exit Function
    End If
    
    totalLength = ws.Cells(rowMatch, colLen).Value
    
    If Not GetAbsoluteStepForObject(totalLength, step_no, prevLen, abs_step, stepH) Then
        FWA = ""
        Exit Function
    End If
    
    If IsTapered(ws, CLng(rowMatch)) Then
        Dim absStepStart As Double
        If abs_step = 1 Then
            absStepStart = 0
        Else
            absStepStart = 7 + CDbl(abs_step - 2) * 3
        End If
        
        Dim actualStart As Double
        actualStart = absStepStart
        If prevLen > actualStart Then actualStart = prevLen
        
        Dim areaAll As Double
        areaAll = GetTaperedStepArea(ws, CLng(rowMatch), totalLength, stepH, prevLen, actualStart, "ALL")
        If areaAll < 0 Then
            FWA = "[ERROR: TAPERED]"
        Else
            FWA = areaAll
        End If
    Else
        colPeriExt = Application.Match("PerimeterExt(S)", ws.Rows(1), 0)
        If IsError(colPeriExt) Then
            FWA = "[NO COLUMN: PerimeterExt(S)]"
            Exit Function
        End If
        
        colPeriInt = Application.Match("PerimeterInt(S)", ws.Rows(1), 0)
        If IsError(colPeriInt) Then
            FWA = "[NO COLUMN: PerimeterInt(S)]"
            Exit Function
        End If
        
        periExt = ws.Cells(rowMatch, colPeriExt).Value
        periInt = ws.Cells(rowMatch, colPeriInt).Value
        FWA = stepH * periExt + stepH * periInt
    End If
    Exit Function
    
ErrHandler:
    FWA = "[ERROR]"
End Function

'============================================================
' FWD - °ÅÇªÁý °øÁ¦ ¸éÀû (FormWork Deduction)
'
' »ç¿ë¹ý: =FWD(0)  ¡æ ½ÃÁ¡(S) ´Ü¸éÀû ¹ÝÈ¯ (FaceArea(S))
'         =FWD(1)  ¡æ Á¾Á¡(E) ´Ü¸éÀû ¹ÝÈ¯ (FaceArea(E))
'
' º¯¼ö:
'   0 = ½ÃÁ¡(Start)
'   1 = Á¾Á¡(End)
'============================================================
Function FWD(se_flag As Long) As Variant
    Dim ws As Worksheet
    Dim myGUID As String
    Dim rowMatch As Variant
    Dim colMatch As Variant
    Dim colName As String
    
    On Error GoTo ErrHandler
    
    If se_flag <> 0 And se_flag <> 1 Then
        FWD = "[INVALID: 0 or 1 only]"
        Exit Function
    End If
    
    If se_flag = 0 Then
        colName = "FaceArea(S)"
    Else
        colName = "FaceArea(E)"
    End If
    
    Set ws = ThisWorkbook.Worksheets("MEMBER")
    
    myGUID = Application.Caller.Worksheet.Cells(Application.Caller.Row, 5).Value
    
    If Len(Trim(myGUID)) = 0 Then
        FWD = "[NO GUID]"
        Exit Function
    End If
    
    rowMatch = Application.Match(myGUID, ws.Columns("E"), 0)
    If IsError(rowMatch) Then
        FWD = "[NO MATCH]"
        Exit Function
    End If
    
    colMatch = Application.Match(colName, ws.Rows(1), 0)
    If IsError(colMatch) Then
        FWD = "[NO COLUMN: " & colName & "]"
        Exit Function
    End If
    
    Dim result As Variant
    result = ws.Cells(rowMatch, colMatch).Value
    If IsEmpty(result) Or Len(Trim(CStr(result))) = 0 Then
        FWD = ""
    Else
        FWD = result
    End If
    Exit Function
    
ErrHandler:
    FWD = "[ERROR]"
End Function

'************************************************************
'
'  3. µµÀå ÇÔ¼ö (Paint)
'
'************************************************************
'============================================================
' PTE - ¿ÜÃø µµÀå ¸éÀû (PainT Exterior)
'
' »ç¿ë¹ý: =PTE()
'
' µî´Ü¸é: Length ¡¿ PerimeterExt(S)
' º¯´Ü¸é: ÃÑÃø¸éÀû ¡¿ ¿ÜÃøµÑ·¹ÇÕ / ÀüÃ¼µÑ·¹ÇÕ
'============================================================
Function PTE() As Variant
    Dim ws As Worksheet
    Dim myGUID As String
    Dim rowMatch As Variant
    Dim colLen As Variant
    Dim colPeri As Variant
    
    On Error GoTo ErrHandler
    
    Set ws = ThisWorkbook.Worksheets("MEMBER")
    
    myGUID = Application.Caller.Worksheet.Cells(Application.Caller.Row, 5).Value
    
    If Len(Trim(myGUID)) = 0 Then
        PTE = "[NO GUID]"
        Exit Function
    End If
    
    rowMatch = Application.Match(myGUID, ws.Columns("E"), 0)
    If IsError(rowMatch) Then
        PTE = "[NO MATCH]"
        Exit Function
    End If
    
    If IsTapered(ws, CLng(rowMatch)) Then
        Dim colSA As Variant, colFAS As Variant, colFAE As Variant
        Dim colPExtS As Variant, colPExtE As Variant
        Dim colPIntS As Variant, colPIntE As Variant
        Dim surfaceArea As Double, faceAreaS As Double, faceAreaE As Double
        Dim periExtS As Double, periExtE As Double
        Dim periIntS As Double, periIntE As Double
        Dim totalLateral As Double, sumExt As Double, sumAll As Double
        
        colSA = Application.Match("SurfaceArea", ws.Rows(1), 0)
        colFAS = Application.Match("FaceArea(S)", ws.Rows(1), 0)
        colFAE = Application.Match("FaceArea(E)", ws.Rows(1), 0)
        colPExtS = Application.Match("PerimeterExt(S)", ws.Rows(1), 0)
        colPExtE = Application.Match("PerimeterExt(E)", ws.Rows(1), 0)
        colPIntS = Application.Match("PerimeterInt(S)", ws.Rows(1), 0)
        colPIntE = Application.Match("PerimeterInt(E)", ws.Rows(1), 0)
        
        If IsError(colSA) Or IsError(colFAS) Or IsError(colFAE) Or _
           IsError(colPExtS) Or IsError(colPExtE) Or _
           IsError(colPIntS) Or IsError(colPIntE) Then
            PTE = "[ERROR: TAPERED]"
            Exit Function
        End If
        
        surfaceArea = ws.Cells(rowMatch, colSA).Value
        faceAreaS = ws.Cells(rowMatch, colFAS).Value
        faceAreaE = ws.Cells(rowMatch, colFAE).Value
        periExtS = ws.Cells(rowMatch, colPExtS).Value
        periExtE = ws.Cells(rowMatch, colPExtE).Value
        periIntS = ws.Cells(rowMatch, colPIntS).Value
        periIntE = ws.Cells(rowMatch, colPIntE).Value
        
        totalLateral = surfaceArea - faceAreaS - faceAreaE
        If totalLateral <= 0 Then
            PTE = ""
            Exit Function
        End If
        
        sumExt = periExtS + periExtE
        sumAll = sumExt + periIntS + periIntE
        
        If sumAll <= 0 Then
            PTE = ""
            Exit Function
        End If
        
        PTE = totalLateral * (sumExt / sumAll)
    Else
        colLen = Application.Match("Length", ws.Rows(1), 0)
        If IsError(colLen) Then
            PTE = "[NO COLUMN: Length]"
            Exit Function
        End If
        
        colPeri = Application.Match("PerimeterExt(S)", ws.Rows(1), 0)
        If IsError(colPeri) Then
            PTE = "[NO COLUMN: PerimeterExt(S)]"
            Exit Function
        End If
        
        Dim totalLength As Double
        Dim perimeter As Double
        totalLength = ws.Cells(rowMatch, colLen).Value
        perimeter = ws.Cells(rowMatch, colPeri).Value
        
        If totalLength <= 0 Or perimeter <= 0 Then
            PTE = ""
            Exit Function
        End If
        
        PTE = totalLength * perimeter
    End If
    Exit Function
    
ErrHandler:
    PTE = "[ERROR]"
End Function

'============================================================
' PTI - ³»Ãø µµÀå ¸éÀû (PainT Interior)
'
' »ç¿ë¹ý: =PTI()
'
' µî´Ü¸é: Length ¡¿ PerimeterInt(S)
' º¯´Ü¸é: ÃÑÃø¸éÀû ¡¿ ³»ÃøµÑ·¹ÇÕ / ÀüÃ¼µÑ·¹ÇÕ
'============================================================
Function PTI() As Variant
    Dim ws As Worksheet
    Dim myGUID As String
    Dim rowMatch As Variant
    Dim colLen As Variant
    Dim colPeri As Variant
    
    On Error GoTo ErrHandler
    
    Set ws = ThisWorkbook.Worksheets("MEMBER")
    
    myGUID = Application.Caller.Worksheet.Cells(Application.Caller.Row, 5).Value
    
    If Len(Trim(myGUID)) = 0 Then
        PTI = "[NO GUID]"
        Exit Function
    End If
    
    rowMatch = Application.Match(myGUID, ws.Columns("E"), 0)
    If IsError(rowMatch) Then
        PTI = "[NO MATCH]"
        Exit Function
    End If
    
    If IsTapered(ws, CLng(rowMatch)) Then
        Dim colSA As Variant, colFAS As Variant, colFAE As Variant
        Dim colPExtS As Variant, colPExtE As Variant
        Dim colPIntS As Variant, colPIntE As Variant
        Dim surfaceArea As Double, faceAreaS As Double, faceAreaE As Double
        Dim periExtS As Double, periExtE As Double
        Dim periIntS As Double, periIntE As Double
        Dim totalLateral As Double, sumInt As Double, sumAll As Double
        
        colSA = Application.Match("SurfaceArea", ws.Rows(1), 0)
        colFAS = Application.Match("FaceArea(S)", ws.Rows(1), 0)
        colFAE = Application.Match("FaceArea(E)", ws.Rows(1), 0)
        colPExtS = Application.Match("PerimeterExt(S)", ws.Rows(1), 0)
        colPExtE = Application.Match("PerimeterExt(E)", ws.Rows(1), 0)
        colPIntS = Application.Match("PerimeterInt(S)", ws.Rows(1), 0)
        colPIntE = Application.Match("PerimeterInt(E)", ws.Rows(1), 0)
        
        If IsError(colSA) Or IsError(colFAS) Or IsError(colFAE) Or _
           IsError(colPExtS) Or IsError(colPExtE) Or _
           IsError(colPIntS) Or IsError(colPIntE) Then
            PTI = "[ERROR: TAPERED]"
            Exit Function
        End If
        
        surfaceArea = ws.Cells(rowMatch, colSA).Value
        faceAreaS = ws.Cells(rowMatch, colFAS).Value
        faceAreaE = ws.Cells(rowMatch, colFAE).Value
        periExtS = ws.Cells(rowMatch, colPExtS).Value
        periExtE = ws.Cells(rowMatch, colPExtE).Value
        periIntS = ws.Cells(rowMatch, colPIntS).Value
        periIntE = ws.Cells(rowMatch, colPIntE).Value
        
        totalLateral = surfaceArea - faceAreaS - faceAreaE
        If totalLateral <= 0 Then
            PTI = ""
            Exit Function
        End If
        
        sumInt = periIntS + periIntE
        sumAll = periExtS + periExtE + sumInt
        
        If sumAll <= 0 Then
            PTI = ""
            Exit Function
        End If
        
        PTI = totalLateral * (sumInt / sumAll)
    Else
        colLen = Application.Match("Length", ws.Rows(1), 0)
        If IsError(colLen) Then
            PTI = "[NO COLUMN: Length]"
            Exit Function
        End If
        
        colPeri = Application.Match("PerimeterInt(S)", ws.Rows(1), 0)
        If IsError(colPeri) Then
            PTI = "[NO COLUMN: PerimeterInt(S)]"
            Exit Function
        End If
        
        Dim totalLength As Double
        Dim perimeter As Double
        totalLength = ws.Cells(rowMatch, colLen).Value
        perimeter = ws.Cells(rowMatch, colPeri).Value
        
        If totalLength <= 0 Or perimeter <= 0 Then
            PTI = ""
            Exit Function
        End If
        
        PTI = totalLength * perimeter
    End If
    Exit Function
    
ErrHandler:
    PTI = "[ERROR]"
End Function

'============================================================
' PTA - µµÀå ÇÕ»ê ¸éÀû (PainT Area)
'
' »ç¿ë¹ý: =PTA()
'
' µî´Ü¸é: Length ¡¿ (PerimeterExt(S) + PerimeterInt(S))
' º¯´Ü¸é: ÃÑ Ãø¸éÀû = SurfaceArea - FaceArea(S) - FaceArea(E)
'============================================================
Function PTA() As Variant
    Dim ws As Worksheet
    Dim myGUID As String
    Dim rowMatch As Variant
    Dim colLen As Variant
    Dim colPeriExt As Variant
    Dim colPeriInt As Variant
    
    On Error GoTo ErrHandler
    
    Set ws = ThisWorkbook.Worksheets("MEMBER")
    
    myGUID = Application.Caller.Worksheet.Cells(Application.Caller.Row, 5).Value
    
    If Len(Trim(myGUID)) = 0 Then
        PTA = "[NO GUID]"
        Exit Function
    End If
    
    rowMatch = Application.Match(myGUID, ws.Columns("E"), 0)
    If IsError(rowMatch) Then
        PTA = "[NO MATCH]"
        Exit Function
    End If
    
    If IsTapered(ws, CLng(rowMatch)) Then
        Dim colSA As Variant, colFAS As Variant, colFAE As Variant
        Dim surfaceArea As Double, faceAreaS As Double, faceAreaE As Double
        Dim totalLateral As Double
        
        colSA = Application.Match("SurfaceArea", ws.Rows(1), 0)
        colFAS = Application.Match("FaceArea(S)", ws.Rows(1), 0)
        colFAE = Application.Match("FaceArea(E)", ws.Rows(1), 0)
        
        If IsError(colSA) Or IsError(colFAS) Or IsError(colFAE) Then
            PTA = "[ERROR: TAPERED]"
            Exit Function
        End If
        
        surfaceArea = ws.Cells(rowMatch, colSA).Value
        faceAreaS = ws.Cells(rowMatch, colFAS).Value
        faceAreaE = ws.Cells(rowMatch, colFAE).Value
        
        totalLateral = surfaceArea - faceAreaS - faceAreaE
        If totalLateral <= 0 Then
            PTA = ""
        Else
            PTA = totalLateral
        End If
    Else
        colLen = Application.Match("Length", ws.Rows(1), 0)
        If IsError(colLen) Then
            PTA = "[NO COLUMN: Length]"
            Exit Function
        End If
        
        colPeriExt = Application.Match("PerimeterExt(S)", ws.Rows(1), 0)
        If IsError(colPeriExt) Then
            PTA = "[NO COLUMN: PerimeterExt(S)]"
            Exit Function
        End If
        
        colPeriInt = Application.Match("PerimeterInt(S)", ws.Rows(1), 0)
        If IsError(colPeriInt) Then
            PTA = "[NO COLUMN: PerimeterInt(S)]"
            Exit Function
        End If
        
        Dim totalLength As Double
        Dim periExt As Double
        Dim periInt As Double
        totalLength = ws.Cells(rowMatch, colLen).Value
        periExt = ws.Cells(rowMatch, colPeriExt).Value
        periInt = ws.Cells(rowMatch, colPeriInt).Value
        
        If totalLength <= 0 Then
            PTA = ""
            Exit Function
        End If
        
        PTA = totalLength * periExt + totalLength * periInt
    End If
    Exit Function
    
ErrHandler:
    PTA = "[ERROR]"
End Function

