Người mới học VBA, gặp khó khăn: Cú pháp, lý luận, thuật toán trong VBA thì vào đây cùng học!

Liên hệ QC

Cô Bé Dễ Thương

Thành viên thường trực
Tham gia
30/9/16
Bài viết
223
Được thích
48
Giới tính
Nữ
Các bạn cùng giống vấn đề như mình, xin hãy chỉ post bài tóm lược và trọng tâm nhất có thể (ngán nhất nhưng phải trọng tâm, xin cảm ơn)
Xin phép ban điều hành GPE cho cháu lập chủ đề này! Khi học VBA cháu thấy khó tìm và không tự nghĩ ra được cú pháp và lý luận dùng trong lập trình VBA.
Chăm đọc code cũng chỉ tìm hiểu được cú pháp và lý luận trong code nhưng đa phần là 50-50 không tìm thấy và nghĩ ra được. Vấn đề này quả là khó với người mới học code.
Mong chủ đề này được các bậc tiền bối chỉ dạy cho cháu(em) để có chút vốn để mày mò học code. Xin cảm ơn tất cả thật nhiều ạ!
(các bạn cùng giồng vấn đề như mình xin hãy post bài theo kiểu như mình ở dưới)
PHP:
Xin mở đầu bằng câu hỏi mà cháu(em) tìm kiếm mãi không thấy để bắt chước:
===================================================
Dim Rng1 as Range, Rng2 as Range, Rng4 as Range, Rng5 as Range
Dim rg as Range ,Rng as Range
===================================================
Cháu muốn gộp các bảng dữ liệu có cùng cấu trúc: Rng1, Rng2 , Rng3, Rng4, Rng5 thành 1 bảng. Mục đích để có thể dùng biến rg dùng vòng lặp For Each
duyệt từ Rng1 rồi đến Rng2 rồi đến Rng3 rồi đến Rng4 rồi đến Rng5. Hậu quả là phải viết ra 5 Sud để duyệt từng cái 1,nếu không gộp được các
Rng1,Rng2,Rng3,Rng4,Rng5 thành 1 bảng.
For Each rg In (Tất cả Rng1 và Rng2  và Rng3  và Rng4 và Rng5).Rows
................................................
Next rg
===================================================
Vậy cú pháp để cho biến rg duyệt "Tất cả các Rng1 và Rng2  và Rng3  và Rng4 và Rng5" trong một vòng lặp này là gì ạ?[CODE]
 
Lần chỉnh sửa cuối:
Xin phép ban điều hành GPE cho cháu lập chủ đề này! Khi học VBA cháu thấy khó tìm và không tự nghĩ ra được cú pháp và lý luận dùng trong lập trình VBA.
Chăm đọc code cũng chỉ tìm hiểu được cú pháp và lý luận trong code nhưng đa phần là 50-50 không tìm thấy và nghĩ ra được. Vấn đề này quả là khó với người mới học code.
Mong chủ đề này được các bậc tiền bối chỉ dạy cho cháu(em) để có chút vốn để mày mò học code. Xin cảm ơn tất cả thật nhiều ạ!
(các bạn cùng giồng vấn đề như mình xin hãy post bài theo kiểu như mình ở dưới)
PHP:
Xin mở đầu bằng câu hỏi mà cháu(em) tìm kiếm mãi không thấy để bắt chước:
===================================================
Dim Rng1 as Range, Rng2 as Range, Rng4 as Range, Rng5 as Range
Dim rg as Range ,Rng as Range
===================================================
Cháu muốn gộp các bảng dữ liệu có cùng cấu trúc: Rng1, Rng2 , Rng3, Rng4, Rng5 thành 1 bảng. Mục đích để có thể dùng biến rg dùng vòng lặp For Each
duyệt từ Rng1 rồi đến Rng2 rồi đến Rng3 rồi đến Rng4 rồi đến Rng5. Hậu quả là phải viết ra 5 Sud để duyệt từng cái 1,nếu không gộp được các
Rng1,Rng2,Rng3,Rng4,Rng5 thành 1 bảng.
For Each rg In (Tất cả Rng1 và Rng2  và Rng3  và Rng4 và Rng5).Rows
................................................
Next rg
===================================================
Vậy cú pháp để cho biến rg duyệt "Tất cả các Rng1 và Rng2  và Rng3  và Rng4 và Rng5" trong một vòng lặp này là gì ạ?[CODE]
Union(Rng1,Rng2,Rng3,...)
 
Upvote 0
Lần chỉnh sửa cuối:
Upvote 0
Chỉ vậy thôi á? Rồi sao nữa? Đặt tiêu đề nghe đầy tính triết lý mà thực tế là hỏi về hàm gộp Range!
Em hoặc ai đó đang học vba thì post chung vào 1 chỗ tiện cho dễ tổng hợp. Nếu có thể thạo rồi em lại viết vào đây cách dùng những cú pháp và lý luận mà em học được.
Thứ nữa là vừa học và thực hành đến đâu có vướng mắc quá mới hỏi ạ!
Em đang dùng Union đúng như bài #3 nhưng khi tạo Key cho Dictionary thì nó lại chỉ hiểu là của mỗi ông thứ nhất. Vừa thực hành thì nảy sinh vấn đề:
1.Không biết Key có tạo ra được từ các bảng trong Union hay là Key chỉ tạo được ở 1 bảng đơn độc thôi?
2. Ghép được Range bằng Union. Với Array có ghép được không?
Xin giúp em ạ!
(Dim ,Set , dữ liệu chuẩn chạy không lỗi mà lại ra mỗi Key bảng đầu tiên, hic chết dở)
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn này cần học lý thuyết cơ bản đã.
Nắm được lý thuyết thì những théc méc kia mặc nhiên sẽ hiểu.
 
Upvote 0
Bạn này cần học lý thuyết cơ bản đã.
Nắm được lý thuyết thì những théc méc kia mặc nhiên sẽ hiểu.
Mong bác hoan hỉ chỉ cho, mỗi thứ 1 ít, mỗi người 1 ít. Vì hiện cháu cũng gắng không hỏi theo kiểu đưa bài lên mà có găng hỏi ít nhất có thể. Vậy là cũng có tiến bộ phải không ạ?
 
Upvote 0
Chắc chủ bài đăng đang tính luyện giải thuật. Mà cái thứ này thì khó hướng dẫn . . . .
Mà theo mình thì xông ngay vô Dictionary làm chi cho tốn sức; Ngược lại, theo mình nên xài những thứ phổ thông cho những trường hợp gây cấn. Lúc đó mới tích lũy giải thuật hay!

Chủ bài đăng thử đến đây & giải theo hướng Dictionary xem sao: https://www.giaiphapexcel.com/diendan/threads/Đánh-số-thứ-tự-theo-ngày-tháng-và-theo-từng-group.154495/ (Ở đó cũng có thêm cách xài phương thức Union() đấy)
 
Lần chỉnh sửa cuối:
Upvote 0
Bác @SA_DQ dậy sớm thế. Nhân bác đang xanh xanh cháu hỏi tý:
Union các Range có cột bằng nhau, nhưng khác số dòng thì có Union đc không. Vì cháu dùng Union trường hợp này là để tạo ra vùng có dữ liệu không trùng lặp (Dictionary). Sau đó mới tạo Key cho Dict nhưng Union rồi mà nó lại hiểu có 1 Range đầu tiên.
 
Lần chỉnh sửa cuối:
Upvote 0
Bác @SA_DQ dậy sớm thế. Nhân bác đang xanh xanh cháu hỏi tý:
Union các Range có cột bằng nhau, nhưng khác số dòng thì có Union đc không. Vì cháu dùng Union trường hợp này là để tạo ra vùng có dữ liệu không trùng lặp (Dictionary). Sau đó mới tạo Key cho Dict nhưng Union rồi mà nó lại hiểu có 1 Range đầu tiên.
Do bạn hỏi nhỏ giọt, không có ví dụ cụ thể, dữ liệu ra sao nên chỉ có gợi ý cho bạn thế này.
Mã:
For Each sCell In Union(Rng1, Rng2, Rng3...).Areas
    MsgBox sCell.Address
Next
Việc còn lại là tùy biến và xử lý.
 
Upvote 0
Union các Range có cột bằng nhau, nhưng khác số dòng thì có Union đc không. Vì cháu dùng Union trường hợp này là để tạo ra vùng có dữ liệu không trùng lặp (Dictionary). Sau đó mới tạo Key cho Dict nhưng Union rồi mà nó lại hiểu có 1 Range đầu tiên.
Đã kêu bạn học lý thuyết cơ bản đã.
Bây giờ mình cứ xoắn quẩy Range, Array, Dictionary vào với nhau làm gì, kết cục không giải quyết gì cả.
Mọi thứ đều bắt nguồn từ khái niệm, định nghĩa. Nắm được cái đó đã mới tính tiếp.
 
Upvote 0
Trong chủ đề bên kia tôi có đề nghị phương pháp suy luận và thực hành lập trình. Bản chất việc suy luận là tìm ra thuật toán phù hợp (chưa cần tối ưu). Nhắc lại và bổ sung như sau:

Phướng pháp là các bước thế này:
1. Tự suy nghĩ về thuật toán (cái gọi là ní nuận ấy): Các bước tuần tự để giải bài toán
2. Ghi ra giấy, nghĩ lại vài lần nữa, chỉnh sửa hoặc sắp xếp lại nếu cần
3. Đối với từng bước, tìm công cụ phù hợp: For Next hay Do, Xài Dict hay không, Nếu xài Dict thì item nên là giá trị gì, xài mảng hay phải xài cell, có cần mảng kết quả không, xài If Then hay xài Select Case, ...
Muốn biết chắc sử dụng công cụ nào là phù hợp thì phải nắm vững lý thuyết cơ bản của từng cấu trúc đó. Đây là điều @befaint nhắc 2 lần
4. Tự viết câu lệnh dựa vào ní nuận đã ghi trên giấy, không copy từng dòng lệnh của người khác, trừ khi biết chính xác là câu lệnh copy đó phù hợp với ní nuận. Việc này để rèn cú pháp.
5. Gán giá trị vào biến xong, xem xét việc sử dụng giá trị biến như thế nào: Tăng dần, cộng dồn, sử dụng lại chỗ này chỗ khác, ...
6. Viết xong chạy thử từng dòng lệnh: Nhấn F8 để chạy từng câu lệnh.
- Sau mỗi câu lệnh, rà chuột vào các biến để xem giá trị tức thời của biến (chỉ xem được biến đơn, không xem được biến mảng hoặc giá trị mảng, giá trị range nhiều ô). Hoặc dùng câu lệnh Debug.Print để xem
- Đối chiếu với giá trị mong muốn
- Nếu code có cấu trúc If, thì xem lệnh chạy đến điều kiện của If rồi chạy thẳng đến else, hay chạy các dòng lệnh của if? Việc này đúng hay sai so với mong muốn?
- Nếu câu lệnh để gán kết quả, thì kết quả có đúng ý chưa
- Nếu có vòng lặp, thì xét ít nhất 3 vòng lặp xem các câu lệnh có chạy đúng ý muốn chưa


TB:
Ní nuận là từ không chính xác trong trường hợp này, Phải nói là tư duy thuật toán
 
Lần chỉnh sửa cuối:
Upvote 0
Đã kêu bạn học lý thuyết cơ bản đã.
Bây giờ mình cứ xoắn quẩy Range, Array, Dictionary vào với nhau làm gì, kết cục không giải quyết gì cả.

TB:
Ní nuận là từ không chính xác trong trường hợp này, Phải nói là tư duy thuật toán
Vâng!
Có 2 chủ đề đã đưa lên GPE đc các bác chỉ dạy cho cháu cũng làm Dictionary cơ ban rồi. Giờ muốn mở rộng ra. Trước là 1 vùng dữ liệu gồm những giá trị duy nhất từ đó có Key của Dict, giờ mở rộng ra gồm nhiều vùng dữ liệu có giá trị duy nhất để tạo Key của Dict.
Hiện cháu xử lý:
1. Có 5 vùng thì làm 5 cai Sub để thực hiện cho 5 vùng(có khả năng lên đến 100 vùng như vậy, tương đương 100 Sub, và file excel nặng hơn và có quá nhiều Sub, và nhiều cột nhiều bảng phụ trên Sheets
2. Trên sheet tạo ra 1 Sub để gộp các vùng đó lại làm 1 bảng. Rồi dùng Dictionary
3. Gộp luôn 5 bảng bằng code rồi xử lý bằng 1 Sub. Hiện cách này Union xử lý cách này cháu chưa làm đc.
Khóc: Cách 2 có lẽ là tối ưu nhất đến hiện tại chăng, hay là có thể có cách 3 chăng?
Chỉ bậc thậy ở GPE mới chỉ được, đọc không và trình hiện tại không xử lý đc
 
Lần chỉnh sửa cuối:
Upvote 0
Vâng!
Có 2 chủ đề đã đưa lên GPE đc các bác chỉ dạy cho cháu cũng làm Dictionary cơ ban rồi. Giờ muốn mở rộng ra. Trước là 1 vùng dữ liệu gồm những giá trị duy nhất từ đó có Key của Dict, giờ mở rộng ra gồm nhiều vùng dữ liệu có giá trị duy nhất để tạo Key của Dict.
Hiện cháu xử lý:
1. Có 5 vùng thì làm 5 cai Sub để thực hiện cho 5 vùng
2. Trên sheet tạo ra 1 Sub để gộp các vùng đó lại làm 1 bảng. Rồi dùng Dictionary
3. Gộp luôn 5 bảng bằng code rồi xử lý bằng 1 Sub. Hiện cách này Union xử lý cách này cháu chưa làm đc.
Dùng Union ghép lung tung dễ bị nầy bị kia
Dùng mảng lưu dữ liệu các vùng. Ví dụ có 3 vùng
sArr=array(range("A3:B5"),range("C6:G10"),range("X20"Z50"))
for i=0 to ubound(sArr)
for each ....

next
next i
 
Upvote 0
Dùng Union ghép lung tung dễ bị nầy bị kia
Dùng mảng lưu dữ liệu các vùng. Ví dụ có 3 vùng
sArr=array(range("A3:B5"),range("C6:G10"),range("X20"Z50"))
for i=0 to ubound(sArr)
for each ....

next
next i
Vâng. Cháu cảm ơn và làm theo ạ
Nếu không được xin phép post bài lên sau ạ!
 
Upvote 0
Xin phép được đặt câu hỏi chung chủ để với chủ bài đăng vì bản thân em cũng là người mới tiếp xúc làm quen với VBA và đang gặp 1 bài khó chưa giải quyết được, mong nhận được chút chỉ giáo của các admin GPE.
Bài toán của em là quản lý kho, trong đó có phần quản lý tổng đơn xuất, nhập trong khoảng thời gian xác định, sau đó show kết quả ra ngay trên userform. phần nhập dữ liệu giao dịch (là nhâp hay xuất), số lượng hàng hóa cụ thể em đã làm được. Xong đến đoạn làm thế nào để viết code đếm số lượng đơn nhập/xuất trong khoảng thời gian xác định và show nó lên thì e mày mò mãi ko đc. Sau đây là đoạn code em đã viết thử và bị báo lỗi:

Sub tinh_tong_don_xuat_nhap()

Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Tinh_tong_don")

ws.Cells.Clear

ThisWorkbook.Sheets("Xuat_nhap").Range("C:C").Copy ws.Range("A1")
ThisWorkbook.Sheets("Xuat_nhap").Range("D:D").Copy ws.Range("B1")

ws.ActiveSheet.Range("$A$1:$B$12").RemoveDuplicates (ws.Range("A"))

'''Tinh_tong_nhap
Dim wsb As Worksheet
Set wsb = ThisWorkbook.Sheets("Bao_cao")

wsb.Range("C7") = "=COUNTIFS(Tinh_tong_don!A:A,""NK*"",Tinh_tong_don!B:B,"">=""&Bao_cao!C1,Tinh_tong_don!B:B,""<=""&Bao_cao!C2)"
wsb.Range("C8") = "=COUNTIFS(Tinh_tong_don!A:A,""XK*"",Tinh_tong_don!B:B,"">=""&Bao_cao!C1,Tinh_tong_don!B:B,""<=""&Bao_cao!C2)"

End Sub

Kính mong các cao nhân giúp em sửa lại cho đúng. Em xin chân thành cảm ơn!!!
Em cũng xin gửi kèm file chi tiết ạ!
 

File đính kèm

  • QL kho theo VBA.xlsm
    48 KB · Đọc: 16
Upvote 0
Được nhờ chú @ptm0412(mong chú phê vài dòng giúp cháu ạ) và các bác mới được đến đây ạ!
Bài dưới đây hiện có 3 cách giải với Dictionary:
1. Key tao ra ở từng bảng có giá trị duy nhất.Nghĩa là có 6 bảng thì có 6 Sub. Sau đó thêm một Sub nữa để ghép các cột kết quả lại với nhau. Đồng nghĩa với viêc dùng tới 7 Sub và 6 cột phụ
2. Gộp tất cả các bảng lại thành 1 bảng duy nhất. Sau đó mới tạo Key. Cách này phải dùng tới 2 Sub và trên Sheets phải thêm dữ liệu 1 bảng
3. Dùng chỉ 1 Sub và không phát sinh cột phụ.Cách 3 hiện chịu thua và cầu cứu sự giúp đỡ của các thầy!
(Hình minh họa cách 2 và code gộp bảng cách 2, và file đính kèm đã hoàn thành 2 cách)
cach2.jpg
Gôp bảng theo cách nhà quê, nông dân, chân đất mắt toét này của em thì xác định tay to hơn chân. Nhưng nom cũng được!
PHP:
Sub ghep_bang()
Dim Rng As Range, RArr()
Dim Rng1 As Range, Rng2 As Range, Rng3 As Range, _
Rng4 As Range, Rng5 As Range, Rng6 As Range
LR1 = Application.WorksheetFunction.CountA(Sheet3.Range("F:F")) - 2
lR2 = Application.WorksheetFunction.CountA(Sheet3.Range("j:j")) - 2
lR3 = Application.WorksheetFunction.CountA(Sheet3.Range("n:n")) - 2
lR4 = Application.WorksheetFunction.CountA(Sheet3.Range("r:r")) - 2
lR5 = Application.WorksheetFunction.CountA(Sheet3.Range("v:v")) - 2
lR6 = Application.WorksheetFunction.CountA(Sheet3.Range("z:z")) - 2

Set Rng1 = Sheet3.Range("F10:H" & LR1 + 9)
Set Rng2 = Sheet3.Range("j10:l" & lR2 + 9)
Set Rng3 = Sheet3.Range("n10:p" & lR3 + 9)
Set Rng4 = Sheet3.Range("r10:t" & lR4 + 9)
Set Rng5 = Sheet3.Range("v10:x" & lR5 + 9)
Set Rng6 = Sheet3.Range("z10:ab" & lR6 + 9)
For i = 1 To LR1 + lR2 + lR3 + lR4 + lR5 + lR6
Set Rng_TT = Sheet3.Range("ad" & i + 9)
Set Rng_Name = Sheet3.Range("ae" & i + 9)
Set Rng_Mon = Sheet3.Range("af" & i + 9)
Rng_TT.Value = i
    If (i <= LR1) Then
            Rng_Name.Value = Rng1.Cells(i, 2)
            Rng_Mon.Value = Rng1.Cells(i, 3)
    End If
    If (i > LR1 And i <= LR1 + lR2) Then
            Rng_Name.Value = Rng2.Cells(i - LR1, 2)
            Rng_Mon.Value = Rng2.Cells(i - LR1, 3)
    End If
    If (i > LR1 + lR2 And i <= LR1 + lR2 + lR3) Then
            Rng_Name.Value = Rng3.Cells(i - LR1 - lR2, 2)
            Rng_Mon.Value = Rng4.Cells(i - LR1 - lR2, 3)
    End If
    If (i > LR1 + lR2 + lR3 And i <= LR1 + lR2 + lR3 + lR4) Then
            Rng_Name.Value = Rng4.Cells(i - LR1 - lR2 - lR3, 2)
            Rng_Mon.Value = Rng4.Cells(i - LR1 - lR2 - lR3, 3)
    End If
    If (i > LR1 + lR2 + lR3 + lR4 And i <= LR1 + lR2 + lR3 + lR4 + lR5) Then
            Rng_Name.Value = Rng5.Cells(i - LR1 - lR2 - lR3 - lR4, 2)
            Rng_Mon.Value = Rng5.Cells(i - LR1 - lR2 - lR3 - lR4, 3)
    End If
    If (i > LR1 + lR2 + lR3 + lR4 + lR5 And i <= LR1 + lR2 + lR3 + lR4 + lR5 + lR6) Then
            Rng_Name.Value = Rng6.Cells(i - LR1 - lR2 - lR3 - lR4 - lR5, 2)
            Rng_Mon.Value = Rng6.Cells(i - LR1 - lR2 - lR3 - lR4 - lR5, 3)
    End If
Next i
End Sub
 

File đính kèm

  • key_dict_tu_nhieu_range.xlsm
    40.1 KB · Đọc: 19
Lần chỉnh sửa cuối:
Upvote 0
Xin phép được đặt câu hỏi chung chủ để với chủ bài đăng vì bản thân em cũng là người mới tiếp xúc làm quen với VBA.................
Mình bảo này, chỗ nào bạn cần chèn code khi post bài lên GPE bạn làm như sau:
CODE=php
Nội dung gì cũng được
/CODE
Nhớ thêm dấu [ ] bọc lấy 2 từ màu đỏ là được nhé
Làm thế các thầy dễ nhìn hơn. Ở đây comment với mình cho vui!
(Hóng cách 3 bài #17)
 
Lần chỉnh sửa cuối:
Upvote 0
Upvote 0
Web KT
Back
Top Bottom