Trao đổi về thuật toán trong lập trình VBA (8 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

PhanTuHuong

VBA & VB.NET for Excel & AutoCad
Thành viên danh dự
Tham gia
13/6/06
Bài viết
7,201
Được thích
24,664
Tôi mở chủ đề này vì thấy ít các nhà lập trình VBA (hay ngôn ngữ khác) quan tâm và không thấy trao đổi.

Hiểu đơn giản nhất: Thuật toán là một dãy hữu hạn các bước, mỗi bước mô tả chính xác các phép toán hoặc hành động cần thực hiện, giải quyết một vấn đề hay bài toán nào đó. Như vậy, để giải quyết một bài toán nào đó, cần phải có trình tự các bước giải quyết, đó là thuật toán.

Trong lập trình, thuật toán đóng vai trò hết sức quan trọng, quyết định đến sự thành công của các bài toán trong VBA. Chúng ta không thể giải được bài toán nếu không nắm được thuật toán (nhiều bạn nhờ giúp đỡ công việc mà chính họ nhiều khi còn hiểu một cách ấm ớ +-+-+-+). Ngoài ra 1 bài toán có thể có nhiều lời giải. Có lời giải khoa học, ngắn gọn, nhanh chóng, có lời giải thì dài dòng... Điều đó phụ thuộc vào tư duy và kỹ năng của mỗi người...
Cũng phải khẳng định nếu không có tư duy thuật toán tốt thì việc xây dựng chương trình lớn trên VBA coi như không khả thi.

Do vậy, tôi lập chủ đề này để chúng ta trao đổi thêm về thuật toán và kỹ năng giải quyết.
 
Lần chỉnh sửa cuối:
trong giáo trình cấu trúc dữ liệu có phát biểu:
giải thuật + cấu trúc dữ liệu = chương trình
(tui suy ra) giải thuật = chương trình - cấu trúc dữ liệu
thật sự là quá rộng để bàn về giải thuật/thuật giải nói chung, chỉ nên trao đổi các vấn đề cụ thể. qua đó mọi người có thể tham khảo, ứng dụng.

Các thuật toán sắp xếp và tìm kiếm cơ bản là nội dung quan trọng nhất trong lập trình, do vậy tôi đã biên tập 1 chuyên đề mang hơi hướng VBA:

 
Upvote 0
Tôi mở chủ đề này vì thấy ít các nhà lập trình VBA (hay ngôn ngữ khác) quan tâm và không thấy trao đổi.

....

Tôi rất ít khi viết code. Thường thì để trả lời một vấn đề nào đó, tôi chỉ đưa ra thuật toán.
Tuy nhiên, tôi thấy hình như không mấy ai để ý đến, và tôi có cảm tưởng là:
1. Phần đông bạn ở đây chỉ thích code chứ không chú ý mặt giải thuật.
2. Phần đông các bạn hỏi không hề quan tâm đến thuật toán, miễn sao dữ liệu -> kết quả là mãn nguyện.

Nhiều cái codde đưa ra, tôi nhìn hoài mà không hiểu do bài giải không đáp ứng được câu hỏi, hay là bài giải đúng nhưng do code không làm đúng theo bài giải.

Theo tôi, muốn nói chuyện về thuật toán thì đầu tiên hết chúng ta phải tập thói quen:

(i) Nói sơ qua là mình hiểu đề bài như thế nào.
(ii) Nói sơ qua là mình đáp ứng đề bài (giải) như thế nào. Nếu cách giải của mình không giản dị như 2+2=4 thì nên nói sơ qua nó dựa trên nguyên lý gì.
(iii) Sau khi có câu đáp án, cho biết giới hạn đáp án của mình (trường hợp nào thì không áp dụng được)

(*) Lưu ý: tôi nói "phần đông" chứ không phải tất cả. Gần đây có một vài vị cũng làm giống nguyên tắc với (i), (ii), (iii) như tôi kể trên.
 
Upvote 0
Đúng là 1 thói quan tồi, mình cũng đến lúc bí, cụt đường mới quay lại viết sơ đồ giải quyết vấn đề của mình cần giải hay tham gia với mọi người giúp cho bạn nào đó.

Rất hay là các bác đã lưu ý đến thói quan tồi này của tôi!

Xin cảm ơn diễn đàn!
 
Upvote 0
Vấn đề được giải quyết đôi khi chẳng thấy có tý toán cho nên gọi thuật giải có vẻ hay hơn.

Dựa vào định nghĩa này thì có thể thấy thuật giải không có gì là quá mới mẻ bởi vì con người từ khi biết tư duy họ đã phải nghĩ ra những trình tự và nguyên tắc logic để giải quyết một số vấn đề trong đời sống của họ. Và cho đến tận một ngày cách đây khoảng 4 thế kỷ, người ta mới nghĩ đến một thuật ngữ bao quát chung đó là từ thuật giải - Algorithm.
(Bạn có thể tìm định nghĩa từ Algorithm trong từ điển).

Có vài thuật giải khá nổi tiếng từ xưa chẳng hạn tìm các số nguyên tố nhỏ hơn 100 theo sàng Eratosthenes. Eratosthenes - người đưa ra giải thuật này sinh năm 276 TCN (cách đây khoảng 23 thế kỷ cơ đấy).

Hay là thuật giải hoán vị mà theo tôi có lẽ có cách đây cả hàng vạn năm.
Thuật giải hoán vị có thể hiểu đơn giản qua một ví như sau: Có một cái thùng A đựng chất AA, và một cái thùng B đựng chất BB. Làm thế nào để kết quả thu được là thùng A đựng chất BB, và thùng B đựng chất AA.

Qủa không khó để giải quyết vấn đề này phải không các anh/chị? Và áp dụng nguyên lý khái quát của thuật giải hoán vị trong việc hoán đổi giá trị của 2 biến trong lập trình ta có như sau:
Mã:
[COLOR=#0000cd][B]C = A
A = B
B = C[/B][/COLOR]
Thuật giải trước thời có máy tính điện tử chắc là đơn giản và thực hiện hữu hạn trong khả năng ghi chép, tính toán, thao tác bằng tay của con người. Nhưng với sự ra đời của máy tính điện tử thì người ta có thể thực hiện được những thuật giải phức tạp ví như dùng vòng lặp vài tỷ lần chẳng hạn.

Trong máy tính điện tử, thuật giải được mô tả bằng các đoạn code. Nhưng nếu suy diễn ngược lại mọi đoạn code là diễn giải của thuật toán nào đó thì chắc... nhầm. Ví dụ người ta xây dựng sẵn một cái hàm sin(x) tìm sin của x. Hỏi một anh viết thuật toán tìm sin của x thì anh viết: y = sin(x)...

Tôi thấy có khá nhiều người lạm dụng từ thuật giải/thuật toán cho bất cứ đoạn code nào họ viết ra chẳng khác nào cái cách một anh mua động cơ, khung, linh kiện... về ráp thành cái xe rồi kêu rằng mình chế tạo ra... cái xe đó.

Thuật giải được mô tả trực quan bằng các lưu đồ diễn giải. Bởi thế nhiều bạn cứ tưởng mình không biết thuật giải nhưng trong các bài luận thì lại chứng tỏ mình khá rành... thuật giải thông qua các lưu đồ diễn tả cách giải quyết nghiệp vụ.

Với người lập trình, thuật giải giống như một bản phác thảo. Nó giúp người lập trình hình dung ra được những tiến trình mà phần mềm sẽ giải quyết theo cách thuật giải mô tả. Công đoạn viết code thực ra chỉ là quá trình chi tiết và cụ thể hóa bản phác thảo đó.

Trên đây phần lớn là cách suy nghĩ của riêng bản thân tôi nên chắc cũng có nhiều điều còn nhầm lẫn mong anh chị góp ý.

Nếu A và B là dữ liệu phức tạp thì phuơng pháp hoán đổi có thể cũng đòi hỏi một thuật toán. Ví dụ (trong ngữ cảnh VBA) A và B là string và con toán cần hoán đổi cỡ vài trăm ngàn lần.

Nếu cái hàm sin có sẵn trong đó ngôn ngữ nó bắt buộc đơn vị của tham số là gradian trong khi tham số được cho là độ thì người ta vẫn cần một thuật toán để thông suốt vấn đề.

trong giáo trình cấu trúc dữ liệu có phát biểu:
giải thuật + cấu trúc dữ liệu = chương trình
(tui suy ra) giải thuật = chương trình - cấu trúc dữ liệu
thật sự là quá rộng để bàn về giải thuật/thuật giải nói chung, chỉ nên trao đổi các vấn đề cụ thể. qua đó mọi người có thể tham khảo, ứng dụng.

Theo lô gic Đại số, con toán hoán vế biểu thức như vậy chỉ có nghĩa khi:

1. Các thành phần là những vật thể có thể đo được (định lượng), và
2. Các thành phần là cùng loại vật thể hoặc có thể ép kiểu (xe máy không thể làm toán với gà vịt)

Có như thế ta mới có thể quy định phép trừ là phép cộng phần tử đối xứng.
 
Upvote 0
Nếu A và B là dữ liệu phức tạp thì phuơng pháp hoán đổi có thể cũng đòi hỏi một thuật toán. Ví dụ (trong ngữ cảnh VBA) A và B là string và con toán cần hoán đổi cỡ vài trăm ngàn lần.

Nếu cái hàm sin có sẵn trong đó ngôn ngữ nó bắt buộc đơn vị của tham số là gradian trong khi tham số được cho là độ thì người ta vẫn cần một thuật toán để thông suốt vấn đề.
Sao anh bạn không bôi luôn dòng
Vô danh tiểu tốt; đã viết:
Và áp dụng nguyên lý khái quát của thuật giải hoán vị trong việc hoán đổi giá trị của 2 biến trong lập trình ta có như sau

Anh có hiểu thế nào là khái quát không ạ? Hay là anh bạn có vẻ nhiệt tình đi vô những cái quá cụ thể, tiểu tiết?

Nếu thuật giải được mô tả chi tiết, cụ thể tới mức cần như anh nói thì thật tình có những thuật giải không tài nào mô tả được đặc biệt là nếu phải dùng lưu đồ vì quá nhiều nhánh, quá nhiều công việc, trường hợp nhỏ nhặt phải liệt kê ra.

Đừng đồng hóa giữa viết code và thuật giải. Thuật giải chỉ cho người ta cái nhìn khái quát của tiến trình giải quyết chứ nó không mang nhiệm vụ chỉ cặn kẽ từng lệnh một. Ví dụ nếu nắm khái quát giải thuật hoán vị thì một người lập trình có đầu óc sẽ hiểu hướng giải quyết thế nào để hoán đổi giá trị của A với B dù cho chúng có là số, chuỗi, mảng, file... gì đi chăng nữa.

Còn để hiểu tại sao ít dùng từ thuật toán (Algorithm) thì các bạn cứ thử thống kê số lần xuất hiện của thuật ngữ này cũng như cách dùng thuật ngữ này trong các tài liệu nói về lập trình bất kỳ nào nhé.
 
Lần chỉnh sửa cuối:
Upvote 0
Sao anh bạn không bôi luôn dòng

Anh có hiểu thế nào là khái quát không ạ? Hay là anh bạn có vẻ nhiệt tình đi vô những cái quá cụ thể, tiểu tiết?

Nếu thuật giải được mô tả chi tiết, cụ thể tới mức cần như anh nói thì thật tình có những thuật giải không tài nào mô tả được đặc biệt là nếu phải dùng lưu đồ vì quá nhiều nhánh, quá nhiều công việc, trường hợp nhỏ nhặt phải liệt kê ra.

Đừng đồng hóa giữa viết code và thuật giải. Thuật giải chỉ cho người ta cái nhìn khái quát của tiến trình giải quyết chứ nó không mang nhiệm vụ chỉ cặn kẽ từng lệnh một. Ví dụ nếu nắm khái quát giải thuật hoán vị thì một người lập trình có đầu óc sẽ hiểu hướng giải quyết thế nào để hoán đổi giá trị của A với B dù cho chúng có là số, chuỗi, mảng, file... gì đi chăng nữa.

Còn để hiểu tại sao ít dùng từ thuật toán (Algorithm) thì các bạn cứ thử thống kê số lần xuất hiện của thuật ngữ này cũng như cách dùng thuật ngữ này trong các tài liệu nói về lập trình bất kỳ nào nhé.

Nếu tôi không lầm thì bạn hiểu thuật toán giống như tôi.
Trước hết cần hiểu chữ "Toán" trong "Thuật toán" không hẳn là Toán (học). Cách nói của người Việt là vậy. Vd. khi nói về một vấn đề khó nào đó trong một lĩnh vực sống nào đó người ta nói: "Đây là một bài toán khó cần giải quyết gấp rút". Không có nghĩa là trong đó có bài Toán khó nào đó.
Thuật toán là thuật toán. Thuật toán không phụ thuộc vào ngôn ngữ lập trình. Thậm chí không hẳn là dính dáng tới lập trình. Nói nôm na thì thuật toán là "các bước đi tuần tự hữu hạn để đạt được kết quả mong muốn nào đó, để giải quyết một vấn đề nào đó trong cuộc sống". Ở đây là nói tới những bước đi chính".

Ta lấy ví dụ vấn đề "lọc duy nhất một danh sách". Thuật toán để giải quyết vấn đề này theo tôi là:
1. Lấy phần tử đầu tiên trong danh sách gốc.
2. Kiểm tra xem trong "danh sách kết quả" đã có phần tử hiện hành chưa. Nếu chưa thì thêm vào.
3. Lấy phần tử tiếp theo nếu còn.
4. Trở lại điểm 2.

Thuật toán chỉ có thế thôi. "danh sách kết quả" là gì, cấu trúc của nó thế nào? Cái này nó không thuộc về thuật toán. Cái này nó là "chi tiết kỹ thuật", là "chi tiết cụ thể". Cách giải quyết những chi tiết cụ thể thuộc về người dùng cái thuật toán đó.

Vd. nếu người giải quyết vấn đề biết lập trình thì anh ta sẽ dùng một cấu trúc dữ liệu nào đó, các cấu trúc ngôn ngữ nào đó để thực hiện những chi tiết của từng bước đi cụ thể. Anh A có thể dùng dictionary làm "danh sách kết quả" và lúc đó anh ta dùng Exists để kiểm tra và dùng Add để thêm vào. Cũng cùng một thuật toán nhưng anh B lại dùng mảng làm "danh sách kết quả", và lúc đó anh ta phải dùng vd. vòng FOR để kiểm tra xem phần tử đã có trong "danh sách kết quả" chưa. Anh C cũng dùng mảng làm "danh sách kết quả" nhưng có vẻ kết nàng "Do...Loop" nên dùng nàng thay cho anh FOR.
Như thế cũng cùng là những bước của thuật toán nhưng các chi tiết cụ thể, chi tiết kỹ thuật thì mỗi người lại có thể giải quyết bằng một cách khác nhau.

Nói tổng quát thì thuật toán không phụ thuộc vào ngôn ngữ lập trình, thậm chí là không liên quan tới lập trình. Nó chỉ là các bước để giải quyết một vấn đề nào đó.

Chẳng hạn như có anh D không có máy tính mà cũng chả biết lập trình. Nhưng anh D hoàn toàn có thể thực hiện các bước của thuật toán để có được danh sách duy nhất. Lúc đó anh D sẽ dùng "sổ tay", "tờ giấy" làm "danh sách kết quả". Và kiểm tra tồn tại bằng cách dò bằng mắt "sổ tay, "tờ giấy". Hoặc nếu có thư ký thì lệnh cho cô thư ký làm việc này. Nếu anh D có sẵn thuật toán sắp xếp thì anh ta cũng sẽ làm và có được danh sách được sắp xếp. Dùng máy tính chẳng qua vì máy tính thao tác cực nhanh và không nhầm lẫn như con người. Thế thôi. Anh D có thể làm 1 năm, 10 năm để có được danh sách được sắp xếp nhưng ở đây cần nhấn mạnh là thuật toán chỉ là các bước hữu hạn để giải quyết một vấn đề nào đó. Bất cứ ai dùng bất cứ công cụ gì - máy tính, xẻng cuốc, bút ... - chỉ cần dùng cái thuật toán "kia" là giải quyết được vấn đề.

Thì thấy ngay thôi. Máy tính, lập trình có từ bao giờ? Còn trong cuộc sống, trong mỗi lĩnh vực, con người từ thủa biết đi đã nghĩ ra từng ngày những thuật toán lớn, nhỏ để giải quyết những vấn đề trong cuộc sống.
Nhưng đã nói tới lập trình thì chắc chắn có thuât toán. Vì người lập trình chẳng qua là chọn cấu trúc dữ liệu, chọn cấu trúc ngôn ngữ, và dùng các hàm để mã một thuật toán sao cho máy có thể hiểu được và thực hiện các bước của thuật toán kia. Tất nhiên mọi chi tiết kỹ thuật thì tùy người mà chúng được giải quyết theo cách khác nhau. Có người giải quyết tốt hơn người kia.

Tóm lại viết code hay lập công thức thì bước đầu tiên bao giờ cũng phải là tìm ra được thuật toán. Bước kế tiếp mới là tìm các công cụ thích hợp (cấu trúc dữ liệu, cấu trúc ngôn ngữ, các hàm có sẵn ...) để thực hiện các bước đã được xác định ở điểm 1. Nhiều khi cũng cùng một hướng đi, một thuật toán nhưng rất có thể 3 người cho 3 công thức khác nhau vì họ dùng các hàm khác nhau vd. để cắt chuỗi (chi tiết kỹ thuật)

Nhiều khi một người biết viết code, tức nắm chắc ngôn ngữ, sử dụng nhuần nhuyễn các cấu trúc dữ liệu, cấu trúc ngôn ngữ, có thể viết mọi code khi có được thuật toán nhưng bản thân anh ta lại rất kém về thuật toán. Nó cũng giống như một anh chàng B chưa hẳn đã được ăn học như anh A nhưng gặp những vấn đề trong cuộc sống anh ta có thể chỉ ra được các bước cần làm để giải quyết vấn đề đó trong khi anh A thì bó tay. Với những người này thì bạn VetMini chỉ cần cho họ thuật toán. Nhưng nếu gặp những người bí về hướng đi mà lập trình trong VBA thì cũng mới chỉ bắt đầu từ "hôm qua" thì bạn cho thuật toán thôi vẫn chưa đủ.

Nói cho cùng thì để nắm được các cơ bản trong lập trình thì chỉ cần 1, 2 tuần. Để sử dụng thạo các cấu trúc dữ liệu, cấu trúc ngôn ngữ thì có thể vài tháng. Nhưng đã nói về thuật toán thì cần cù chưa đủ. Phải luyện tư duy. Tất nhiên cũng có cái phải đọc, phải học, nhưng phải luyện tư duy, tích lũy kinh nghiệm. Với mỗi vấn đề phải ngồi và viết ra giấy được các bước chính cần phải làm để giải quyết vấn đề. Tức phải nghĩ ra được thuật toán. Còn sau đó thực hiện bằng tay hay bằng máy thì tùy.
 
Lần chỉnh sửa cuối:
Upvote 0
Đây là thớt mà chủ đề bắt đầu bằng từ "trao đổi". Khi bước vào đây, tôi đã không có dự định bảo vệ quan điểm của mình. Những gì tôi đưa ra chỉ là một trong nhiều chiều hướng để nhìn sự việc. Những gì tôi moi móc người khác chỉ có nghĩa là hỏi lại: "khi tôi đứng trên góc nhìn của bạn thì tôi còn chưa rõ cái này, cái này..."

Chủ để cũng kết thúc bằng từ "VBA" cho nên tôi giữ phạm vi nó trong VBA. Nếu là ngôn ngữ khác, môi trường khác thì thuật toán hoán đổi A-B có thể là một cách nào đó mà không cần đến C (hoặc không thể sử dụng C). Ví dụ như nếu các thùng giống in hệt nhau thì người ta chỉ cần đổi nhãn A và B với nhau, không cần phải trút chất AA và chất BB ra. Khi tôi nói đến cái này trong bài trước đây thì ngụ ý câu hỏi của tôi là thứ nhất: "trong phạm vi của VBA, có cái gì cho phép làm tương tự như vậy không"; thứ hai: "theo đòi hỏi của đề bài hoán đổi AA và BB trong A-B, ta có cần phải giữ nguyên hai cái thùng A và B hay không"

Tóm lại, đề tài ở đây là trao đổi. Tôi đưa ra góc nhìn để phân tích. Chuyện phê bình đúng sai là chuyện của trẻ con.
 
Upvote 0
1. Các thành phần là những vật thể có thể đo được (định lượng), và
2. Các thành phần là cùng loại vật thể hoặc có thể ép kiểu (xe máy không thể làm toán với gà vịt)

Có như thế ta mới có thể quy định phép trừ là phép cộng phần tử đối xứng.

xe máy, gà vịt có thể dùng "đơn vị" là thứ, là món, là loại ... nên cũng đếm được mà.
dùng "thứ nguyên" thay cho "đơn vị" sẽ chuẩn hơn. có hẳn một môn tên là "lý thuyết thứ nguyên" đấy (có điều không mấy người biết món này).
mặt khác ký hiệu "+" không hẳn là "phép toán cộng", đôi khi "+" được hiểu là "và", đôi khi đơn giản chỉ là "chữ thập"...

VD: Công thức của Lenin: CNXH = Chính quyền Xô-viết + Điện khí hóa toàn quốc
(đề nghị không bình luận hay suy ra gì đó, tui chỉ có ý lấy dẫn chứng về cách dùng dấu "+" )
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu là ngôn ngữ khác, môi trường khác thì thuật toán hoán đổi A-B có thể là một cách nào đó mà không cần đến C (hoặc không thể sử dụng C). Ví dụ như nếu các thùng giống in hệt nhau thì người ta chỉ cần đổi nhãn A và B với nhau, không cần phải trút chất AA và chất BB ra.
Nói như anh thì chúng ta không phải dùng đến một đối tượng trung gian nào ah? Anh có thể đưa ra một ví dụ minh họa trong bất cứ ngôn ngữ lập trình nào được không ạ?
Khi tôi nói đến cái này trong bài trước đây thì ngụ ý câu hỏi của tôi là thứ nhất: "trong phạm vi của VBA, có cái gì cho phép làm tương tự như vậy không";
Hình như anh không có ý niệm về "khái quát" thì phải? Khi minh họa bằng

C = A
A = B
B = C

Phép gán C = A có thể hiểu là copy nội dung từ A sang C. Ví dụ A chứa giá trị 1, hiển nhiên sau phép gán C = A, C cũng là 1. Vậy phép gán hay copy ở đây cũng tương đương nhau. Nếu A và C là kiểu dữ liệu phức tạp đi chăng thì lúc này chúng ta hiểu là phép copy và hiển nhiên là chúng ta sẽ có thủ tục copy. Tôi có thể minh họa lại

Copy(C, A)
Copy(A, B)
Copy(B, C)

Với một cái hàm có cú pháp Copy(đích, nguồn)

Nhưng chẳng nhẽ cữ mỗi một cái thuật toán thì người ta cứ phải liệt kê tất tần tật những trường hợp cụ thể có khả năng xảy ra hay sao? Giả sử nếu một ông thầy dạy thuật toán hoán vị với ví dụ dùng kiểu số thì cả đời anh sinh viên lập trình chỉ biết dùng thuật toán ấy cho mỗi kiểu số thôi à?
thứ hai: "theo đòi hỏi của đề bài hoán đổi AA và BB trong A-B, ta có cần phải giữ nguyên hai cái thùng A và B hay không"
Nếu cứ theo những đòi hỏi ngặt nghèo như này thì đến cả ông tác giả đã nêu ra ví dụ mà tôi đã mượn trích lại cũng đành bó tay.
 
Lần chỉnh sửa cuối:
Upvote 0
Hình như anh không có ý niệm về "khái quát" thì phải? Khi minh họa bằng

C = A
A = B
B = C

Phép gán C = A có thể hiểu là copy nội dung từ A sang C. Ví dụ A chứa giá trị 1, hiển nhiên sau phép gán C = A, C cũng là 1. Vậy phép gán hay copy ở đây cũng tương đương nhau. Nếu A và C là kiểu dữ liệu phức tạp đi chăng thì lúc này chúng ta hiểu là phép copy và hiển nhiên là chúng ta sẽ có thủ tục copy. Tôi có thể minh họa lại

Copy(C, A)
Copy(A, B)
Copy(B, C)

đừng kỹ quá làm gì, bạn bình luận sao về câu lệnh

i = i + 1

(đến giờ mỗi khi viết lệnh này cứ như nhai phải sạn, tui thích kiểu viết i++ của C hơn)

chỉ là trao đổi ý kiến, có phải trả bài khi thi đâu.
 
Upvote 0
bạn bình luận sao về câu lệnh: i = i + 1
Để trả lời được câu này thì trước tiên xin được hỏi "bạn có biết thứ tự thực thi trong đoạn lệnh đó không ạ?". Nếu biết rồi thì chắc bạn tự có câu trả lời. Còn nếu chưa biết thì vui lòng tự tìm hiểu vấn đề đó vì nếu không chúng ta lan man qua những chuyện chẳng ăn nhập gì cả.
 
Lần chỉnh sửa cuối:
Upvote 0
Nhưng chẳng nhẽ cữ mỗi một cái thuật toán thì người ta cứ phải liệt kê tất tần tật những trường hợp cụ thể có khả năng xảy ra hay sao? .

Tất nhiên là không.

Thuật toán là thuật toán. Không có chuyện đi vào các chi tiết cụ thể. Cách thực hiện thuật toán thì tùy người "thực hiện" (implementation). Chúng chỉ khác nhau về các chi tiết kỹ thuật. Và tùy từng trường hợp cụ thể mà chi tiết kỹ thuật ấy có hình hài thế nào. Bản chất của hoán vị là dùng một đối tượng, một nơi trung gian. Nếu hiểu như thế thì đổi chỗ 2 học sinh A và B chẳng qua là: Cho A nhẩy sang, ngồi sang một chỗ tạm thời --> cho B nhẩy vào chỗ A --> cho A nhẩy vào chỗ B. Về bản chất thì nó giống như hoán vị giá trị của 2 biến.

Theo tôi dấu "=" người ta dùng để minh họa thuật toán mà thôi. Cũng có thể dùng ký tự khác nhưng dùng ký tự "=" nó trực quan, dễ hiểu nhất. Nhưng không có nghĩa là đó là phép "gán" thông thường. Trong trường hợp 2 biến Long chẳng hạn thì đó là phép gán giá trị thông thường. Nhưng nếu đó là 2 cấu trúc chẳng hạn thì lúc đó cái gán kia phải hiểu là ta tạo một cấu trúc trung gian, ta làm một bản sao của A, sau đó ...

Ta lấy vd. bubble sort. Ai đó nói: "nhưng dùng thuật toán đó không sắp xếp được danh sách họ tên người Việt. Phải tìm thuật toán cho sắp xếp tên người Việt thôi". Làm gì có thuật toán bubble sort khác. Nhiều khi để dùng một công cụ, một thuật toán nào đấy thì chả phải chuẩn bị gì cả. Nhưng nhiều khi phải có bước chuẩn bị. Đó là đưa dữ liệu đầu vào tới dạng thích hợp để có thể dùng công cụ hay thuật toán kia. Vd. đó là bước mã họ tên thành dạng không có dấu thanh để chắc chắn sau khi dùng bubble sort kia thì ta có thứ tự đúng. Bước cuối cùng là chuyển những mã trên về lại họ và tên. Bước cuối cùng cũng có thể làm theo cách khác. Vd. "họ tên" là những dòng trong mảng thì ta tạo thêm một mảng mà giá trị các phần tử là những chỉ số liên tiếp của "họ tên - mã" kia trong mảng nguồn. Khi hoán vị 2 mã thì ta cũng hoãn vị 2 chỉ số tương ứng. Như thế thì sau khi thực hiện sort thì ta có trong mảng tạo thêm thứ tự cần có của các dòng trong mảng nguồn. Cũng có thể không dùng mảng mới mà ta thêm 1 cột vào mảng nguồn để ghi các chỉ số kia. Tất cả những thao tác "chuẩn bị" và "kết thúc" kia là những chi tiết cụ thể của trường hợp cụ thể. Thuật toán là tổng quát. Thuật toán chỉ chỉ ra những bước cần thực hiện, không đi vào chi tiết, không phán là các bước đó phải thực hiện như thế nào. Việc thực hiện những bước đó thế nào thì tùy vào trường hợp cụ thể, tùy vào người implement cái thuật toán kia.

Tôi hiểu sao nói vậy. Tất nhiên tôi không dám cho là chỉ có tôi hiểu đúng.
Tôi không tranh luận với bạn đâu nhé. Vì thực ra tôi có cảm giác là về khía cạnh này tôi và bạn hiểu như nhau. Chỉ là mượn câu của bạn làm điểm xuất phát cho những nhận xét, ý kiến của mình.
 
Upvote 0
Tôi hiểu sao nói vậy. Tất nhiên tôi không dám cho là chỉ có tôi hiểu đúng.
Tôi không tranh luận với bạn đâu nhé. Vì thực ra tôi có cảm giác là về khía cạnh này tôi và bạn hiểu như nhau. Chỉ là mượn câu của bạn làm điểm xuất phát cho những nhận xét, ý kiến của mình.
Anh và em hiểu như nhau có gì phải tranh luận nữa nhỉ?
Chắc em phải né chủ đề này thôi vì cảm giác bị đẩy đến chỗ vượt quá sức diễn giải rồi. Pó tay...
 
Upvote 0
...

i = i + 1

(đến giờ mỗi khi viết lệnh này cứ như nhai phải sạn, tui thích kiểu viết i++ của C hơn)

...

Theo đúng lẽ thì ở đây là phạm vi của VBA, nói chuyện C là trật đề. Nhưng bạn đem ví dụ này ra thì tôi tự cảm thấy cần tránh các bạn khác phải hiểu lầm.

C là ngôn ngữ vốn bắt nguồn từ ngôn ngữ viết hệ điều hành. Ngôn ngữ này quan niệm về "lệnh" khác với VBA. Ta có thể tạm ví lệnh trong VBA với sub và lệnh trong C với function. Nói cách khác, một lệnh trong C chạy xong rồi còn trả về một trị - mục đích để liên kết lệnh (pipe).

Vì vậy, trong VBA, i = i+1 chỉ là một lệnh tăng trị của i lên 1. Nhưng trong C, i = i+1 thực ra khác với i++ ; tuy chúng cùng có tác dụng tăng i lên 1 nhưng trị trả về của chúng khác nhau. VD

int j, i;
i = 5;
j = i++; // i ở đây là 6, nhưng trị trả về của i++ là 5 cho nên j là 5
i = 5;
j = i = i+1; // i ở đây là 6, trị trả về của i = i+1 là 6 cho nên j là 6
// đây chỉ là ví dụ, thực tế muốn j là 6 thì người ta viết j = ++i;

Xin lỗi tôi nói hơi lạc đề một chút. Chủ yếu chỉ muốn giải thích lệnh gán = của VBA khác với cách áp dụng của C.

Thời sơ khai ngôn ngữ BASIC, toán tử = chỉ được dùng để so sánh. Muốn dùng nó trong lệnh gán phải kèm thêm từ khoá Let.
 
Lần chỉnh sửa cuối:
Upvote 0
Vậy nên mình xin đưa ra ví dụ đầu tiên; Xin các bạn có trên trăm bài về VBA chỉ gợi í lúc cần & khoan làm trước!

Đề bài viết rõ như sau:
LẬP BÁO CÁO THEO TỪNG ĐƠN VỊ

Gỉả dụ chúng ta có 1 CSDL cấp fát hàng cho các đơn vị (gồm nhóm, đội hay tổ) độc lập gồm các trường như sau:


Ngay|MaHang|TenHang|SoLuong|MaDV
1/5/13|ABC01|Bộ chuyển đổi|49|BM
…|…|…||
1/19/13|CCA09|Điều khiển|103|CS
…|…|…||
…|…|…||
2/15/13|ADC01|Máy biến tầng|90|BH
…|…|…||
3/9/13|CBA09|Máy fát điện|17|KS1
…|…|…||

Ở cột cuối ghi mã đơn vị trong công ti nhận hàng; Tên của các đơn vị trực thuộc này được liệt kê theo bảng sau:


TenDV|MaDV
Đội Bình minh|BM
Nhóm Biến hóa|BH
Đội Kiểm soát|KS1
Tổ Sửa chữa|SC
…..|…

Nhiệm vụ đề ra là:

Tạo 1 trang báo cáo có tiêu đề ở dòng 4 như sau:
BÁO CÁO QUYẾT TOÁN NHẬP-XUẤT-TỒN CỦA TỔ SỬA CHỮA.

Nội dung báo cáo giống như bảng dưới đây:

TT|MaVT|TenVT, hàng hóa|Tồn ĐK|SL Nhập| SL Xuất |Tồn CK|Ghi chú

Để có báo cáo này, các bạn cần viết 1 macro sự kiện gắn kết với 1 ô validation để chọn tên các đơn vị thành viên. Sau khi chọn lựa thành viên nào đó thì số liệu của đơn vị đó hiện lên bảng báo cáo!

Chúc vui!

Thuật dùng ngôn ngữ truy vấn dữ liệu T-SQL, không dùng VBA. Các thành viên tham khảo, nếu không dùng Addin A-Tools thì có thể dùng ADO để thực thi T-SQL
 

File đính kèm

Upvote 0
Tôi mở chủ đề này vì thấy ít các nhà lập trình VBA (hay ngôn ngữ khác) quan tâm và không thấy trao đổi.

Hiểu đơn giản nhất: Thuật toán là một dãy hữu hạn các bước, mỗi bước mô tả chính xác các phép toán hoặc hành động cần thực hiện, giải quyết một vấn đề hay bài toán nào đó. Như vậy, để giải quyết một bài toán nào đó, cần phải có trình tự các bước giải quyết, đó là thuật toán.

Trong lập trình, thuật toán đóng vai trò hết sức quan trọng, quyết định đến sự thành công của các bài toán trong VBA. Chúng ta không thể giải được bài toán nếu không nắm được thuật toán (nhiều bạn nhờ giúp đỡ công việc mà chính họ nhiều khi còn hiểu một cách ấm ớ +-+-+-+). Ngoài ra 1 bài toán có thể có nhiều lời giải. Có lời giải khoa học, ngắn gọn, nhanh chóng, có lời giải thì dài dòng... Điều đó phụ thuộc vào tư duy và kỹ năng của mỗi người...
Cũng phải khẳng định nếu không có tư duy thuật toán tốt thì việc xây dựng chương trình lớn trên VBA coi như không khả thi.

Do vậy, tôi lập chủ đề này để chúng ta
trao đổi thêm về thuật toánkỹ năng giải quyết.
Mình có ý kiến thế này: " Có thể không đúng thì bỏ qua nhưng là trao đổi mà" Đọc qua các bài của các bạn dường như tại chủ topic đầu tiên đưa ra cái rộng quá
1: Mở topic để trao đổi: Cái này đang đạt mục đích " số bài tham gia khá nhiều"
2: Thêm : Dường như mới chỉ đang có thuật "hoán vị" đang được trao đổi
3: Thuật toán : Đề tài mà chủ topic muốn mọi người hướng tới để trao đổi "đang sôi nổi định nghĩa lại"
4: kỹ năng giải quyết: Theo mình hiểu thì ý của chủ topic muốn nói tới kỹ năng xây dụng thuật.
>>Nếu còn đang tranh luận thế nào là thuật mình đọc bài các bạn và nói cái hiểu của mình như vầy: "Thuật giải" như các bạn cũng đã nói nó là trình tự giải quyết vấn đề để đạt được cái mong muốn. Xây dựng thuật có thể đơn giản là các gạch đầu dòng "như dạng dàn bài viết văn" , có khi là sơ đồ rẽ nhánh theo các trường hợp...sau đó ta lựa chọn công cụ để giải quyết " ngôn ngữ: VBA, VB,C..."
VD: Mình có một hộp bi đủ các màu mình muốn biết có bao nhiêu màu bi và mỗi lạoi màu có bao nhiêu viên bi?
Vậy với yêu cầu của mình có bao nhiêu thuật để giải và cái gì để ta xây dựng ra cái thuật đó, với thuật đó áp dụng được cho những dạng công việc nào???
Mình có chút tham gia như trên thiếu sót mong được chỉ bảo!!!
 
Upvote 0
VD: Mình có một hộp bi đủ các màu mình muốn biết có bao nhiêu màu bi và mỗi lạoi màu có bao nhiêu viên bi?
Vậy với yêu cầu của mình có bao nhiêu thuật để giải và cái gì để ta xây dựng ra cái thuật đó, với thuật đó áp dụng được cho những dạng công việc nào???
Mình có chút tham gia như trên thiếu sót mong được chỉ bảo!!!
Tôi thì chẳng biết thuật toán là cái gì hết, khi gặp một vấn đề cần giải quyết gì thì tôi cứ làm sao cho ra được chính xác kết quả yêu cầu, thế là xong! }}}}}

Với bài toán viên bi này, tôi nghĩ cứ lựa màu nào ra màu đó, đếm được bao nhiêu màu, tổng số bi của mỗi màu cộng lại với nhau sẽ ra tổng số viên bi của cả hộp. Còn ứng dụng nó cho cái gì tôi cũng chẳng biết, người ta yêu cầu làm gì mình làm cái đó thôi, còn người ta ứng dụng cho cái gì thì đó là việc của người ta ... ẹc ... ẹc .... |||||
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi thì chẳng biết thuật toán là cái gì hết, khi gặp một vấn đề cần giải quyết gì thì tôi cứ làm sao cho ra được chính xác kết quả yêu cầu, thế là xong! }}}}}

Với bài toán viên bi này, tôi nghĩ cứ lựa màu nào ra màu đó, đếm được bao nhiêu màu, tổng số bi của mỗi màu cộng lại với nhau sẽ ra tổng số viên bi của cả hộp. Còn ứng dụng nó cho cái gì tôi cũng chẳng biết, người ta yêu cầu làm gì mình làm cái đó thôi, còn người ta ứng dụng cho cái gì thì đó là việc của người ta ... ẹc ... ẹc .... |||||
Mình thấy anh em bàn luận muốn có tư duy lập trình thì phải rèn luyện xây dựng thuật trước khi viết code!

Vậy với thuật của bạn mình làm theo các bước nhé:
B1: chuẩn bị các hộp trống khác "mục đính là để đựng bi _ số lượng hộp cần chưa xác định đuợc"
B2: Nhặt 1 viên bi trong hộp ban đầu.
B3: Xác định màu của bi đang cầm
B4: Lây 1 hộp trống ra và "ghi" nhãn cho nó là màu của viên bi đang cầm
B5: Đặt viên bi đó vào hộp trên
B6: Nhặt 1 viên bi khác ở hộp ban đầu
B7: Xác định màu của viên bi đang cầm
B8: Kiểm tra nhãn của hộp đựng bi đã có nhãn sem có hộp nào có tên nhãn cùng màu với viên bi đang cầm hay không
Có: Thì đặt viên bi đó vào
Không: -Lây 1 hộp trống ra và "ghi" nhãn cho nó là màu của viên bi đang cầm
-Đặt viên bi đó vào hộp trên
Làm lập lại các bước từ B6>>>B8 cho tới hết số bi trong hộp ban đầu
B9:Đếm số hộp được ghi nhãn màu bi >>> số màu bi có
B10: Lấy từng hộp bi có nhãn màu đếm số bi>>>mỗi màu có bao nhiêu bi
Xin cho hỏi cách của HOÀNG TRỌNG NGHĨA đây đã phải là thuật giải cho yêu cầu giải quyết vấn đề của mình chưa?
 
Upvote 0
Với bài toán viên bi này, tôi nghĩ cứ lựa màu nào ra màu đó, đếm được bao nhiêu màu, tổng số bi của mỗi màu cộng lại với nhau sẽ ra tổng số viên bi của cả hộp. Còn ứng dụng nó cho cái gì tôi cũng chẳng biết, người ta yêu cầu làm gì mình làm cái đó thôi, còn người ta ứng dụng cho cái gì thì đó là việc của người ta ... ẹc ... ẹc .... |||||

Đó là bài toán TỔNG HỢP VÀ TÍNH TỔNG thôi mà (như PivotTable ấy)
Với VBA, cứ dùng Dictionary là xong chuyện:
- Kiểm tra nếu chưa có màu thì thêm màu vào Key, đồng thời cho số lượng vào Item
- Nếu đã có màu rồi thì lấy số lượng cộng dồn vào số lượng đã có (cùng key)
- Đếm số màu thì chính là Dic.Count
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom