เพื่อมุ่งให้เกิดคุณภาพจากการอบรมสูงสุด Excel Expert Training ให้การอบรม Excel กลุ่มเล็กๆ ไม่เกิน 6 คนทุกคนสามารถเรียนรู้ Excel อย่างใกล้ชิด จะมาคนเดียวหรือมาเป็นกลุ่มแล้วนัดวันอบรมแบบส่วนตัวก็ได้ ผู้เข้าอบรมทุกคนสามารถติดตามเนื้อหาที่อบรมได้อย่างชัดเจนจากจอภาพด้านหน้าของตัวเอง
Page 2 of 2 FirstFirst 12
Results 11 to 17 of 17

Thread: จะดึงค่าจากตำแหน่งอ้างอิง 3 มิติได้อย่างไร

  1. #11
    สมเกียรติ
    Guest
    ผมสร้างตัวอย่างเพื่อประกอบรหัสที่สร้างมา พบว่ายังมีสิ่งที่น่าปรับปรุงให้ดีขึ้น (ดูตารางส่วนที่พื้นสีชมพูครับ) คือ
    1. สูตรแบบที่ไม่ใส่ค่าในวงเล็บ จะคำนวณใหม่ต่อเมื่อกดปุ่ม Ctrl+Alt+F9 (Excel 2003) เท่านั้น และจะได้คำตอบซ้ำกันทุกชีต น่าปรับปรุงให้คำนวณใหม่เองเมื่อเรากด F9 และให้คำตอบต่างกันไปตามแต่ละชีต
    2. กรณีที่อ้างอิงถึงตำแหน่งเซลล์ สูตรจะตีความว่าเป็น Range ในชีตนั้นเสมอ อยากให้รหัสแยกตรวจสอบค่าใน Range ที่อ้างมาว่า ถ้ามีค่าเป็นเลข ให้ตีความว่าเป็นเลขที่ชีตที่ต้องการหาชื่อชีต และถ้ามีค่าเป็น text ให้เทียบกับชื่อชีตที่มีก่อน ถ้าตรงกับชื่อชีตที่มีให้ตีความว่า เป็นชื่อชีตที่ต้องการหาเลขที่ชีต จะได้ไม่ต้องพิมพ์ค่าลงไปในสูตรโดยตรง
    ผมลองใส่ Application.Volatile ไม่ได้ช่วยให้ F9 สั่งคำนวณค่าใหม่ แล้วลองใช้ If Isnumeric(shName) แทรกใน Select Case "Range" กลับทำให้กรณีเป็น Range จริงไม่งาน

    ขอรบกวนด้วยครับ

  2. #12
    สมเกียรติ
    Guest
    ขอเพิ่มรายละเอียดจากคำแนะนำข้างต้นครับ

    ไม่ทราบว่าสิ่งที่ผมต้องการจะเหมาะสมไหม เช่น A1 มีค่าเป็นตัวเลข 2
    =SheetName(A1)
    จะให้คำตอบเป็นชื่อชีตลำดับที่สอง

    แต่ถ้า A1 ไม่มีค่าเป็นตัวเลข หรือ A1 เป็นเซลล์ว่างไม่มีค่าใดๆ
    =SheetName(A1)
    จะให้คำตอบเป็นชื่อชีตของเซลล์ A1 โดยที่อาจใช้เซลล์ใดเซลล์หนึ่งในชีตอื่นก็ได้และจะได้คำตอบเป็นชื่อชีตนั้นๆ

    แต่ถ้าพิมพ์ค่าคงที่ลงไปในวงเล็บ
    =SheetName(2)
    จะได้ชื่อชีตลำดับที่สอง

    หลักการที่คิดไว้ คือ การสร้างสูตรโดย link ค่ามาจากเซลล์อื่น จะทำให้สูตรคำนวณได้ยืดหยุ่นกว่าการใส่ค่าคงที่ใดๆไว้ในวงเล็บของสูตร

    ส่วนสูตร SheetIndex ขอใช้หลักการคล้ายกันกับ SheetName ครับ แต่ให้ SheetIndex ตรวจสอบค่าในเซลล์ที่อ้าง ว่าเป็นชื่อชีต (แทนที่จะเป็นเลขตามกรณีของ SheetName)

  3. #13
    อรวีร์
    Guest

    Smile

    ลองทดลองดูค่ะว่าตรงกับที่ต้องการหรือไม่
    Code:
    Function Cell3D(Ref As Range, ShNo)
        Cell3D = Sheets(ShNo).Range(Ref.Address).Value
    End Function
     
    Function SheetIndex(Optional ShName) As Integer
        Application.Volatile
        If IsMissing(ShName) Then
            SheetIndex = Application.Caller.Parent.Index + Now() * 0
        Else
            Select Case TypeName(ShName)
                Case "Range"
                    If TypeName(ShName.Value) = "String" Then
                        SheetIndex = Sheets(ShName.Value).Index
                    Else
                        SheetIndex = ShName.Parent.Index
                    End If
                Case "String", "Double"
                    SheetIndex = Sheets(ShName).Index
            End Select
        End If
    End Function
     
    Function SheetCount() As Integer
        Application.Volatile
        SheetCount = Worksheets.Count
    End Function
     
    Function SheetName(Optional ShName) As String
        Application.Volatile
        If IsMissing(ShName) Then
            SheetName = Application.Caller.Parent.Name
        Else
            Select Case TypeName(ShName)
                Case "Range"
                    If TypeName(ShName.Value) = "Double" Then
                        SheetName = Sheets(ShName.Value).Name
                    Else
                        SheetName = ShName.Parent.Name
                    End If
                Case "String", "Double"
                    SheetName = Sheets(ShName).Name
            End Select
        End If
    End Function
     
    Function Cell_3D(Ref As Range, ParamArray ShNo()) As Variant()
        Dim Arr(), I As Integer, J As Integer
        If UBound(ShNo) > 0 Then
            If TypeName(ShNo(0)) = "String" Then ShNo(0) = Sheets(ShNo(0)).Index
            If TypeName(ShNo(1)) = "String" Then ShNo(1) = Sheets(ShNo(1)).Index
            J = ShNo(1) - ShNo(0)
            Arr = Array(Sheets(ShNo(0)).Range(Ref.Address).Value)
            ReDim Preserve Arr(J)
            For I = 1 To J
                Arr(I) = Sheets(ShNo(0) + I).Range(Ref.Address).Value
            Next
            Cell_3D = Arr
        Else
            Cell_3D = Sheets(ShNo(0)).Range(Ref.Address).Value
        End If
    End Function

  4. #14
    สมเกียรติ
    Guest
    ขอบคุณครับ สังเกตเห็นคุณอรวีร์ใช้ Volatile กับ Now() เพื่อทำให้ F9 ทำงาน ซึ่งน่าจะมีทางอื่น แต่ผมเองก็ใช้แบบเดียวกันเพราะเข้าใจง่ายดี

    ผมได้สร้างตัวอย่างใหม่มาให้ดูด้วยครับ ผมลองกดปุ่ม F9 ในแฟ้มอื่น จะพบว่าสูตรในแฟ้มนี้ error ขึ้นมา ต้องกลับมาที่แฟ้มนี้แล้วกด F9 สูตรจึงจะทำงานใหม่
    แต่ขอพอใจแค่นี้ก่อนครับ ขอบคุณคุณอรวีร์มากครับ

  5. #15
    อรวีร์
    Guest

    Smile

    ขออภัยค่ะ ที่ยังมี + Now() * 0 นั้นตัดออกได้ค่ะ ตอนทดสอบเสร็จลืมลบออก

  6. #16
    อรวีร์
    Guest

    Smile

    ลอง Code ที่แก้มาใหม่นี้ค่ะ
    สำหรับการ Recal. ที่แฟ้มอื่นได้ค่ะ
    Code:
    Function Cell3D(Ref As Range, ShNo)
        Cell3D = Application.Caller.Parent.Parent.Sheets(ShNo).Range(Ref.Address).Value
    End Function
     
    Function SheetIndex(Optional ShName) As Integer
        Application.Volatile
        If IsMissing(ShName) Then
            SheetIndex = Application.Caller.Parent.Index
        Else
            With Application.Caller.Parent.Parent
            Select Case TypeName(ShName)
                Case "Range"
                    If TypeName(ShName.Value) = "String" Then
                        SheetIndex = .Sheets(ShName.Value).Index
                    Else
                        SheetIndex = ShName.Parent.Index
                    End If
                Case "String", "Double"
                    SheetIndex = .Sheets(ShName).Index
            End Select
            End With
        End If
    End Function
     
    Function SheetCount() As Integer
        Application.Volatile
        SheetCount = Application.Caller.Parent.Parent.Worksheets.Count
    End Function
     
    Function SheetName(Optional ShName) As String
        Application.Volatile
        If IsMissing(ShName) Then
            SheetName = Application.Caller.Parent.Name
        Else
            With Application.Caller.Parent.Parent
            Select Case TypeName(ShName)
                Case "Range"
                    If TypeName(ShName.Value) = "Double" Then
                        SheetName = .Sheets(ShName.Value).Name
                    Else
                        SheetName = ShName.Parent.Name
                    End If
                Case "String", "Double"
                    SheetName = .Sheets(ShName).Name
            End Select
            End With
        End If
    End Function
     
    Function Cell_3D(Ref As Range, ParamArray ShNo())
        Dim Arr(), I As Integer, J As Integer
        With Application.Caller.Parent.Parent
        If UBound(ShNo) > 0 Then
            If TypeName(ShNo(0)) = "Range" Then ShNo(0) = ShNo(0).Value
            If TypeName(ShNo(1)) = "Range" Then ShNo(1) = ShNo(1).Value
            If TypeName(ShNo(0)) = "String" Then ShNo(0) = .Sheets(ShNo(0)).Index
            If TypeName(ShNo(1)) = "String" Then ShNo(1) = .Sheets(ShNo(1)).Index
            Arr = Array(.Sheets(ShNo(0)).Range(Ref.Address).Value)
            J = ShNo(1) - ShNo(0)
            ReDim Preserve Arr(J)
            For I = 1 To J
                Arr(I) = .Sheets(ShNo(0) + I).Range(Ref.Address).Value
            Next
            Cell_3D = Arr
        Else
            Cell_3D = .Sheets(ShNo(0)).Range(Ref.Address).Value
        End If
        End With
    End Function

  7. #17
    สมเกียรติ
    Guest
    ใช้ได้แล้วครับ ขอบคุณมาก
    หลายวันก่อนคอมพิวเตอร์ที่บ้านเจอไวรัสบุกอีกครั้ง ต้องกู้ระบบกลับมาโดยใช้ Acronis TrueImage แล้ววันต่อมาติดอบรมที่สสทเลยไม่ได้ตอบผลให้ทราบทันทีครับ

    ผมลองนำไปสร้างเป็น Addin ต่อ แต่รหัสใช้ไม่ได้กับแฟ้มอื่น ขอรบกวนคุณอรวีร์ช่วยดูรหัสต่อให้ด้วยครับ ไม่ทราบว่าจะทำได้ไหม เท่าที่คิดคือน่าจะใช้ ActiveWorkbook, ActiveSheet มาช่วย

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •