EXCEL TOOLS
Excel Add-ins ที่พัฒนาโดยคุณสันติพงศ์ ณสุย (MVP Excel 2010-2020) ด้วยภาษา C# เพื่อแก้ไขปัญหาไฟล์ใหญ่ คำนวณนาน ทำงานช้า จัดการข้อมูลต่าง ๆ ที่ทำงานประจำวันได้อย่างสะดวกรวดเร็ว สนใจคลิกไปดูได้ที่นี่ครับ => Excel Tools
Excel Add-ins ที่พัฒนาโดยคุณสันติพงศ์ ณสุย (MVP Excel 2010-2020) ด้วยภาษา C# เพื่อแก้ไขปัญหาไฟล์ใหญ่ คำนวณนาน ทำงานช้า จัดการข้อมูลต่าง ๆ ที่ทำงานประจำวันได้อย่างสะดวกรวดเร็ว สนใจคลิกไปดูได้ที่นี่ครับ => Excel Tools
[code]
และปิดด้วย [/code]
ตัวอย่างเช่น [code]dim r as range[/code]
เพื่อให้แตกต่างจากข้อความทั่วไป สะดวกในการอ่านและทดสอบ (คลิกเพื่อดูตัวอย่าง)Code: Select all
Sub averi()
Dim avi As String 'ตัวแปรเพื่อเก็บค่าเฉลี่ย
Dim row As Integer 'วนแถว
Dim col As Integer 'วนคอลัมน์
row = 4
col = 6
Do While Worksheets(1).Cells(row, col).Value <> ""
col = col + 1
Worksheets(1).Cells(row, col).Select
Loop
'Worksheets(1).Range = Left(F4, 1)
'Worksheets(1).Cells(4, AP).Value = avi
End Sub
Code: Select all
Dim allRng As Range, r As Range
Dim lastRow As Long, st As String
Dim rh As Range, mt As Long
With ActiveSheet
lastRow = .Range("a" & .Rows.Count).End(xlUp).row
Set allRng = .Range("ap4", .Range("ba" & lastRow))
For Each r In allRng
st = VBA.Right(.Cells(2, r.Column), 1)
mt = Application.Match(st, .Range("f2:ao2"), 0)
Set rh = Application.Index(.Range("f2:ao2"), mt).MergeArea
r.Value = Application.Sum(.Cells(r.row, rh.Column) _
.Resize(, rh.Columns.Count)) / rh.Columns.Count
Next r
End With
*อยากทราบว่าถ้าหากเกิดการเพิ่มหรือลดคำถามที่ใช้ในการประเมินซึ่งมีผลต่อคอลัมน์ที่ลดหรือเพิ่มตามคำถามเช่นกัน กรณีแบบนี้สามารถแก้ปัญหาได้อย่างไรบ้างค่ะsnasui wrote: ตัวอย่าง Code ครับCode: Select all
Dim allRng As Range, r As Range Dim lastRow As Long, st As String Dim rh As Range, mt As Long With ActiveSheet lastRow = .Range("a" & .Rows.Count).End(xlUp).row Set allRng = .Range("ap4", .Range("ba" & lastRow)) 'Code บรรทัดนี้มันระบุคอลัมน์แรก(ap4) ที่ใช้โชว์ค่าเฉลี่ยแต่ละประเภทจนถึงคอลัมน์สุดท้าย(ba) เป็นคอลัมน์ตายตัว ซึ่งหากในแต่ละปีจะมีการเพิ่มลดหรือลดคำถามที่ใช้ในการประเมินนั้นจะไม่สามารถหาค่าเฉลี่ยเนื่องจาก Code ได้ระบุคอลัมน์ตายตัวไว้ค่ะ For Each r In allRng st = VBA.Right(.Cells(2, r.Column), 1) mt = Application.Match(st, .Range("f2:ao2"), 0) 'Code บรรทัดนี้เป็น code ที่ใช้ในการนับคอลัมน์รึเปล่าค่ะโดยอ้างจากตัวอักษรที่อยู่ในคอลัมน์("f2:ao2") ถ้าใช่กลัวว่าหากเกิดการเพิ่มหรือลดคำถามที่ใช้ในการประเมินนั้นจะทำให้ผลของค่าเฉลี่ยมีปัญหาได้ค่ะ Set rh = Application.Index(.Range("f2:ao2"), mt).MergeArea r.Value = Application.Sum(.Cells(r.row, rh.Column) _ .Resize(, rh.Columns.Count)) / rh.Columns.Count Next r End With
ให้ยกมาเฉพาะตัวที่อ่านแล้วไม่เข้าใจมาถาม ไม่ควรให้ผมแปล Code ทั้งหมด การใช้ Code VBA จะต้องศึกษามาตามลำดับ สามารถปรับปรุงแก้ไขเองได้บ้าง กรณีเขียนไม่เป็น ไม่เข้าใจเลย ยังไม่เหมาะที่จะใช้ VBA ครับsbac2558 wrote:ขอบคุณมากนะค่ะ เดี๋ยวจะลองทำก่อนมีปัญหายังไงจะมาต่อกระทู้นะค่ะ
*รบกวนอาจารย์อธิบายCode ทีส่งมาให้สักนิดได้ไหมค่ะ บางบรรทัดยังไม่เข้าใจว่าCode บรรทัดนี้คือการทำอะไร อยากขออนุญาติรบกวนให้อาจารย์อธิบายให้หน่อยได้ไหมค่ะ อีกอย่างหนูอยากเข้าใจในส่วนของCode ด้วยค่ะ
อ่านด้านบนครับsbac2558 wrote:อาจารย์ค่ะ รบกวนอาจารย์อธิบายตัวแปรแต่ละตัวว่ามันเป็นตัวแปรของอะไรเก็บค่าตัวไหนอยู่ หนูอยากลองแก้ไข code ดูแต่แก้ไม่ถูกเพราะไม่รู้ว่าตัวแปรนั้นเป็นตัวแปรของอะไรค่ะ
Datatype ที่เป็น Range คือ คือการประกาศตัวแปรให้เป็นเซลล์หรือช่วงเซลล์sbac2558 wrote:Dim allRng As Range, r As Range 'Range คือชนิดข้อมูลรึเปล่าค่ะหนูยังไม่ได้เรียนRangeในเรื่องของการประกาศตัวแปรก็เลยยังไม่เข้าใจ code บรรทัดนี้ค่ะ
สามารถแปลเช่นนั้นก็ได้ แต่ในส่วนกำหนดค่าให้กับตัวแปรนั้นขึ้นอยู่กับเรา ไม่ใช่ว่าต้องใช้เฉพาะเรื่องใดเรื่องหนึ่ง จะใช้นับแถวหรือใช้นับอย่างอื่นก็ขึ้นอยู่กับความต้องการครับsbac2558 wrote:Dim lastRow As Long, st As String 'ตัวแปรlastRow ใช้ในการนับแถวลงมาใช้เก็บข้อมูลแบบตัวเลขจำนวนเต็มส่วนตัวแปร st ใช้ในการเก็บค่าข้อความ
ตัวแปร rh ขึ้นไปอ่านตามด้านบนครับsbac2558 wrote:Dim rh As Range, mt As Long ตัวแปร rh ไม่ทราบค่ะ ส่วนตัวแปร mt ใช้เก็บข้อมูลแบบตัวเลขจำนวนเต็ม
เป็นการกำหนดค่าให้กับตัวแปร lastRow ให้มีค่าเท่ากับบรรทัดสุดท้ายในคอลัมน์ A มีมีข้อมูลsbac2558 wrote:lastRow = .Range("a" & .Rows.Count).End(xlUp).row 'การนับเลื่อนขึ้นโดยเรื่มต้นจากคอลัมน์ a โค้ดRows.Count ไม่แน่ใจว่าเป็นการนับแถวรึเปล่าค่ะ
.Rows.Count
คือการนับบรรทัดทั้งหมดที่มีในชีตนั้น .End(xlUp)
คือขึ้นไปบรรทัดบนสุดที่มีข้อมูลเป็นการกำหนดค่าให้กับตัวแปร allRng โดยให้เป็นช่วงเซลล์ที่เริ่มตั้งแต่ AP4 จนถึง BA บรรทัดตามค่า lastRowsbac2558 wrote:Set allRng = .Range("ap4", .Range("ba" & lastRow)) 'กำหนดให้คอลัมน์ ap4 จนถึงคอลัมน์ ba แถวล่าสุดที่มีข้อมูลแสดงค่าของตัวแปร allRng
ส่วนนี้เป็นการกำหนดค่าให้กับตัวแปร st ว่าให้เท่ากับอักขระขวาสุดของsbac2558 wrote:st = VBA.Right(.Cells(2, r.Column), 1) 'ในส่วนนี้ไม่เข้าใจค่ะเป็นการให้เซลล์เลื่อนไปทางขวาโดยกำหนดแถวให้เป็นแถวที่2 เท่านั้นมีเพียงคอลัมน์ที่เลื่อน
.Cells(2, r.Column)
.Cells(2,r.column)
คือเซลล์ในบรรทัดที่ 2 ส่วนคอลัมน์ที่เท่าไรนั้น ให้ดูตามคอลัมน์ของตัวแปร rVBA.Right(...,1)
เป็นการตัดค่าด้านขวาของค่าใด ๆ มา 1 อักขระส่วนนี้เป็นการกำหนดค่าให้กับตัวแปร mt ว่าให้มีค่าเท่ากับลำดับที่พบตัวแปร st ในช่วงเซลล์ F2:AO2sbac2558 wrote:mt = Application.Match(st, .Range("f2:ao2"), 0) 'ค้นหาข้อมูลจากเซลล์ f2 จนถึง ao2
ส่วนนี้เป็การกำหนดค่าให้กับตัวแปร rh โดยให้เป็นเซลล์ใดในลำดับที่ mt จากช่วงเซลล์ F2:AO2 (F2 ลำดับที่ 1, G2 ลำดับที่ 2, ...) โดยพิจารณาถึงพื้นที่มีมีการ Merge เอาไว้ด้วย หาก Merge กัน 100 เซลล์ ตัวแปร rh ก็จะมี 100 เซลล์ เช่นนี้เป็นต้นsbac2558 wrote:Set rh = Application.Index(.Range("f2:ao2"), mt).MergeArea 'ดึงข้อมูลจากเซลล์ f2 จนถึง ao2 ที่มาจากการผสานเซลล์
ส่วนนี้เป็นการกำหนดให้ค่าตัวแปร r มีค่าเท่ากับยอดรวมของช่วงข้อมูลsbac2558 wrote:r.Value = Application.Sum(.Cells(r.row, rh.Column) _ 'หาผลรวมจากเซลล์ ในส่วนนี้ไม่เข้าใจค่ะเพราะไม่รู้ว่าตัวแปร rh และ r คือตัวแปรของอะไร รวมถึง _ ที่ไม่รู้ความหมายของมันค่ะ
.Resize(, rh.Columns.Count)) / rh.Columns.Count 'code บรรทัดนี้ ไม่แนใจว่ามันคือการปรับขนาดของคอลัมน์ที่ใช้ในการนับคอลัมน์รึเปล่านะค่ะ
.Cells(r.row, rh.Column).Resize(, rh.Columns.Count))
หารด้วยจำนวนความกว้างคอลัมน์ของตัวแปร rh.Resize(, rh.Columns.Count)
คือการขยายขนาดของ .Cells(r.row, rh.Column)
ไปด้านขวาเท่ากับค่าของ rh.Columns.Count
โดย rh.Columns.Count
คือจำนวนคอลัมน์ทั้งหมดของตัวแปร rhCode: Select all
Dim lastCol As Integer, lastRow As Integer
Dim rAll As Range, r As Range
Dim itemCount As Integer, matItem As Integer
Dim hd As Variant, st As String
hd = Array("ค่าเฉลี่ย i", "ค่าเฉลี่ย s", "ค่าเฉลี่ย m", "ค่าเฉลี่ย a", _
"ค่าเฉลี่ย r", "ค่าเฉลี่ย t", "ค่าเฉลี่ย i1", "ค่าเฉลี่ย h", "ค่าเฉลี่ย a1", _
"ค่าเฉลี่ย p", "ค่าเฉลี่ย p1", "ค่าเฉลี่ย y")
With ActiveSheet
lastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
lastRow = .Cells(.Rows.Count, 1).End(xlUp).row
.Cells(2, lastCol + 1).Resize(1, UBound(hd)).Value = hd
'...Other code
End With
กรณีคำถามไม่เกี่ยวข้องกันควรตั้งกระทู้ใหม่ครับsbac2558 wrote:ต้องการตั้งกระทู้ใหม่เกี่ยวกับการดึงข้อมูลจากsheet ไปอีก sheet หนูต้องทำตั้งกระทู้ใหม่หรือต่อกระทู้นี้เลยค่ะ