Page 1 of 1

ขอคำปรึกษาเรื่องการเขียน VBA ดึงข้อมูลจากอีก Sheet หนึ่ง

Posted: Mon Jul 25, 2016 4:09 pm
by golfgall3
ขอคำปรึกษาเรื่องการเขียน VBA ดึงข้อมูลจากอีก Sheet หนึ่ง
เป็นมือใหม่ครับเลยลองหัดเขียนดู เลยอยากจะขอคำแนะนำจากพี่ๆในนี้ครับ
ผมได้สร้าง sheet ขึ้นมาสองอัน คือ Data กับ Input ผมต้องการอยากจะดึงค่าที่เป็นตัวเลขจาก Input มาใส่ใน Data
โดยมีเงื่อนไขครับ
1.ถ้า Column H ใน Data เท่ากับ ค่าใน column A ใน Input ให้ดึงข้อมูลตัวเลขมา หรือ Copy ตัวเลขมา โดยให้ข้ามช่องที่เป็นสีเหลือง เนื่องจากผมจะใส่สูตรไว้ครับ
2.อยากให้ VBA สามารถอ้างอิง No1-5 ใน Raw ด้วยครับ


ตอนนี้ผมลองเขียนได้เพียงเท่านี้เอง T_T

Code: Select all

Sub atselect()
Dim itemno As Range
Worksheets("Data").Activate
    For Each itemno In Range("H2:H21")
    itemno.Select
        If ActiveCell = Sheets("Input").Range("A2") Then
            ActiveCell.Offset(0, -6).Value = Sheets("Input").Range("B2")
        Else
            ActiveCell.Offset(0, -6).Value = "NODATA"
        End If
    Next itemno
End Sub
รบกวนพี่ๆ แนะนำด้วยครับ

Re: ขอคำปรึกษาเรื่องการเขียน VBA ดึงข้อมูลจากอีก Sheet หนึ่ง

Posted: Mon Jul 25, 2016 6:00 pm
by DhitiBank
ลองแบบนี้ดูครับ

Code: Select all

Sub test()
    Dim iTemNo As Range, rColA As Range, lCount As Long, _
        rHeadNo1 As Range, rHeadNo2 As Range, rFind As Range, r As Range
    Set rHeadNo1 = ActiveSheet.Range("b1:f1")
    Set rHeadNo2 = Sheets("input").Range("b1:e1")
    Set rColA = Sheets("input").Range("a2:a9")
    For Each iTemNo In Range("h2:h21")
        lCount = Application.CountIf(rColA, iTemNo)
        If lCount > 0 Then
            lCount = Application.Match(iTemNo, rColA, 0) + 1
            For Each r In rHeadNo1
                Set rFind = rHeadNo2.Find(what:=r.Value)
                If Not rFind Is Nothing Then
                    r.Offset(iTemNo.Row - r.Row, 0).Value = _
                                rFind.Offset(lCount - 1, 0).Value
                Else
                    r.Offset(iTemNo.Row - r.Row, 0).Value = "NoData"
                End If
            Next r
        End If
    Next iTemNo
End Sub

Re: ขอคำปรึกษาเรื่องการเขียน VBA ดึงข้อมูลจากอีก Sheet หนึ่ง

Posted: Mon Jul 25, 2016 6:34 pm
by golfgall3
ขอบคุณครับ
อธิบาย การทำงานของ Code คร่าวๆ ได้ไหมครับเพื่อจะได้เป็นแนวทางและนำไปประยุกต์ต่อครับ

และถ้าจะเพิ่มปุ่มให้เพื่อให้ VBA รันที่หน้า Input ผมต้องใส่
Worksheets("Data").Activate ด้วยหรือไม่ครับ

Re: ขอคำปรึกษาเรื่องการเขียน VBA ดึงข้อมูลจากอีก Sheet หนึ่ง

Posted: Mon Jul 25, 2016 9:49 pm
by golfgall3
อยากทราบว่า คำสั่งชุดนี้มันมีหลักการคิดยังไงครับ

Code: Select all

If Not rFind Is Nothing Then
                    r.Offset(iTemNo.Row - r.Row, 0).Value = _
                                rFind.Offset(lCount - 1, 0).Value
                Else
                    r.Offset(iTemNo.Row - r.Row, 0).Value = "NoData"
                End If

Re: ขอคำปรึกษาเรื่องการเขียน VBA ดึงข้อมูลจากอีก Sheet หนึ่ง

Posted: Mon Jul 25, 2016 10:46 pm
by DhitiBank

Code: Select all

Sub test()
    Dim iTemNo As Range, rColA As Range, lCount As Long, _
        rHeadNo1 As Range, rHeadNo2 As Range, rFind As Range, r As Range
     '~~>สร้างตัวแปรช่วงที่สนใจเพื่อเอามาอ้างอิงสะดวกครับ
    Set rHeadNo1 = ActiveSheet.Range("b1:f1")
    Set rHeadNo2 = Sheets("input").Range("b1:e1")
    Set rColA = Sheets("input").Range("a2:a9")
    '~~>เริ่มลูปจากการไล่ช่วง h2:h21 ทีละเซลล์โดยแทนด้วยตัวแปร iTemNo
    For Each iTemNo In Range("h2:h21")
        '~~> นับดูว่า iTemNo มีในช่วง rColA หรือไม่
        lCount = Application.CountIf(rColA, iTemNo)
        '~~> หากมีก็ให้รันคำสั่งต่อไปนี้ จะได้ลดเวลาการรันคำสั่ง
        '~~> ไม่ต้องไล่หาทุกค่าใน h2:h21 ครับ
        If lCount > 0 Then
            '~~> ดูว่าค่า iTemNo อยู่ในบรรทัดไหนใน rColA
            '~~> เพื่อเอามาใช่เลื่อนแกนในคำสั่ง Offset
            lCount = Application.Match(iTemNo, rColA, 0) + 1
            '~~> เริ่มลูปเพื่อตรวจหัวคอลัมน์ จะได้ดึงข้อมูล
            '~~> ในคอลัมน์ชื่อเดียวกันมาใส่ ผมใช้คำสั่ง Find คล้ายๆ กับ
            '~~> การกด ctrl+f ในเวิร์คชีทครับ
            For Each r In rHeadNo1
                Set rFind = rHeadNo2.Find(what:=r.Value)
                '~~> หากพบค่า r ใน rHeadNo2 ก็จะสามารถ
                '~~> เซ็ต rFind ได้ คือมันจะได้เป็น range ใดก็ตาม
                '~~> ใน rHeadNo2 แต่ถ้าหาไม่พบ rFind ก็จะไม่มีอะไรเลย
                '~~> คือ nothing ครับ... If ด้านล่างนี้เป็นปฏิเสธซ้อน
                '~~> ปฏิเสธ "ถ้า rFind ไม่ใช่ Nothing ก็ให้..."
                If Not rFind Is Nothing Then
                     '~~> คำสั่งจากนี้เป็นการเลื่อนแกนด้วย offset
                     '~~> ลองค่อยๆดูครับ ว่าเอาแถวอะไรลบอะไร
                     '~~> และเอาค่าที่ match ที่หาไว้ก่อนหน้านี้มาใช้
                    r.Offset(iTemNo.Row - r.Row, 0).Value = _
                                rFind.Offset(lCount - 1, 0).Value
                Else
                    r.Offset(iTemNo.Row - r.Row, 0).Value = "NoData"
                End If
            Next r
        End If
    Next iTemNo
End Sub
ลองกดปุ่ม F8 ให้รันทีละบรรทัดก็ได้ครับ อาจดูง่ายขึ้น ส่วนเรื่องการตั้งปุ่มที่ชีท Input ก็อาจเปลี่ยนโค้ดตรง ActiveSheet โดยอ้างชื่อชีทไปเลย จะได้ไม่ต้องสั่ง Activate ครับ (ตอนเขียนผมรันจากชีทแรก)

Re: ขอคำปรึกษาเรื่องการเขียน VBA ดึงข้อมูลจากอีก Sheet หนึ่ง

Posted: Mon Jul 25, 2016 11:33 pm
by golfgall3
ขอบคุณมากคับ ตอนนี้ผมลองไล่กด F8 ศึกษาดูแล้วคับ
ผมมาติดบันทัด

Code: Select all

CODE: SELECT ALL
If Not rFind Is Nothing Then
   r.Offset(iTemNo.Row - r.Row, 0).Value = _
   rFind.Offset(lCount - 1, 0).Value
Else
   r.Offset(iTemNo.Row - r.Row, 0).Value = "NoData"
End If
เช่น
สมมติ itemno = H4 ดังนั้น itemno.row = 4
ส่วน r.row = 1
ดังนั้น r.offset(itemno.row - r.row,0).value = _
จะเท่ากับ r.offset(3,0).value = emtry

และ rFind.offset(ICount-1,0).Value จะได้ค่าที่อยู่ในตาราง Input

ผมเข้าใจถูกต้องไหมคับ
ผมมีข้อสงสัยคับ
1.สัญลักษณ์ _ มีความหมายว่างอย่างไรคับ
2.r.Offset(iTemNo.Row - r.Row, 0).Value = _
rFind.Offset(lCount - 1, 0).Value
มีความสัมพันธ์กันยังไง เมื่อยู่ใน if not ... is nothing then

Re: ขอคำปรึกษาเรื่องการเขียน VBA ดึงข้อมูลจากอีก Sheet หนึ่ง

Posted: Tue Jul 26, 2016 6:47 am
by snasui
golfgall3 wrote:ขอบคุณมากคับ ตอนนี้ผมลองไล่กด F8 ศึกษาดูแล้วคับ
ผมมาติดบันทัด

Code: Select all

CODE: SELECT ALL
If Not rFind Is Nothing Then
   r.Offset(iTemNo.Row - r.Row, 0).Value = _
   rFind.Offset(lCount - 1, 0).Value
Else
   r.Offset(iTemNo.Row - r.Row, 0).Value = "NoData"
End If
เช่น
สมมติ itemno = H4 ดังนั้น itemno.row = 4
ส่วน r.row = 1
ดังนั้น r.offset(itemno.row - r.row,0).value = _
จะเท่ากับ r.offset(3,0).value = emtry

และ rFind.offset(ICount-1,0).Value จะได้ค่าที่อยู่ในตาราง Input

ผมเข้าใจถูกต้องไหมคับ
ผมมีข้อสงสัยคับ
1.สัญลักษณ์ _ มีความหมายว่างอย่างไรคับ
2.r.Offset(iTemNo.Row - r.Row, 0).Value = _
rFind.Offset(lCount - 1, 0).Value
มีความสัมพันธ์กันยังไง เมื่อยู่ใน if not ... is nothing then
:D ช่วยโพสต์ใหม่ให้เป็นไปตามกฎการใช้บอร์ดข้อ 1 ด้านบนครับ :roll:

Re: ขอคำปรึกษาเรื่องการเขียน VBA ดึงข้อมูลจากอีก Sheet หนึ่ง

Posted: Tue Jul 26, 2016 7:06 am
by golfgall3
:| ขอโทษครับอาจารย์

Re: ขอคำปรึกษาเรื่องการเขียน VBA ดึงข้อมูลจากอีก Sheet หนึ่ง

Posted: Tue Jul 26, 2016 9:13 am
by DhitiBank
golfgall3 wrote:ผมมาติดบันทัด

Code: Select all

If Not rFind Is Nothing Then
   r.Offset(iTemNo.Row - r.Row, 0).Value = _
   rFind.Offset(lCount - 1, 0).Value
Else
   r.Offset(iTemNo.Row - r.Row, 0).Value = "NoData"
End If
เช่น
สมมติ itemno = H4 ดังนั้น itemno.row = 4
ส่วน r.row = 1
ดังนั้น r.offset(itemno.row - r.row,0).value = _
จะเท่ากับ r.offset(3,0).value = emtry

และ rFind.offset(ICount-1,0).Value จะได้ค่าที่อยู่ในตาราง Input
จริงๆ แล้ว

Code: Select all

r.Offset(iTemNo.Row - r.Row, 0).Value = _
   rFind.Offset(lCount - 1, 0).Value
มันก็คือ r.Offset(iTemNo.Row - r.Row, 0).Value = rFind.Offset(lCount - 1, 0).Value ครับ เป็นการสั่ง r.Offset(.....).value ให้มีค่าเท่ากับ rFind.offset(.....).value การใช้เครื่องหมาย underscore _ เพื่อตัดบรรทัดยาวๆ มองลำบากให้ขึ้นบรรทัดใหม่ โดยที่โปรแกรมถือว่าเป็นบรรทัดเดียวกันครับ

Re: ขอคำปรึกษาเรื่องการเขียน VBA ดึงข้อมูลจากอีก Sheet หนึ่ง

Posted: Tue Jul 26, 2016 10:07 am
by golfgall3
ขอบคุณมากครับ ตอนนี้ Code ใช้ได้ดีมากครับ