Giúp học viết một Function

Liên hệ QC

tueyennhi

Thành viên tích cực
Tham gia
18/10/10
Bài viết
1,187
Được thích
105
Chào anh chị!

Giả sử em có đoạn code sau:
PHP:
                        Select Case Ca
                            'Tu 8h den 20h +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>
                        Case "N"
                            If Vao > T6 Then
                                If Vao <= T8 Then
                                    If Ra < T21 Then
                                        If Ra >= T20 Then
                                            Arr(j, 10) = T8
                                            Arr(j, 11) = T20
                                        End If
                                    End If
                                End If
                            End If
                            'Tu 20h den 8h +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>
                        Case "D"
                            If Vao > T18 Then
                                If Vao <= T20 Then
                                    If Ra < T33 Then
                                        If Ra >= T32 Then
                                            Arr(j, 10) = T20
                                            Arr(j, 11) = T32
                                        End If
                                    End If
                                End If
                            End If
                        Case "H"
                            If Vao > T6 Then
                                If Vao <= T8 Then
                                    If Ra < T18 Then
                                        If Ra >= T17 Then
                                            Arr(j, 10) = T8
                                            Arr(j, 11) = T17
                                        End If
                                    End If
                                End If
                            End If
                            'Tu 6h den 14h +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>
                        Case "X"
                            If Vao <= T6 Then
                                If Ra < T15 Then
                                    If Ra >= T14 Then
                                        Arr(j, 10) = T6
                                        Arr(j, 11) = T14
                                    End If
                                End If
                            End If
                            
                            'Tu 14 den 22h +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>
                        Case "Y"
                            If Vao > T10 Then
                                If Vao <= T14 Then
                                    If Ra < T23 Then
                                        If Ra >= T22 Then
                                            Arr(j, 10) = T14
                                            Arr(j, 11) = T22
                                        End If
                                    End If
                                End If
                            End If
                            
                            'Tu 22h den 6h +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>
                        Case "Z"
                            If Vao > T20 Then
                                If Vao <= T22 Then
                                    If Ra < T31 Then
                                        If Ra >= T30 Then
                                            Arr(j, 10) = T22
                                            Arr(j, 11) = T30
                                        End If
                                    End If
                                End If
                            End If
                        End Select
Với Ca dạng Text, Vao-Ra dạng Thời gian có dữ liệu ngày giờ phút giây, Txx là số giờ (Ví dụ T30 là 30h, T8 là 8h) là tham số truyền vào. Arr(j, 10) và Arr(j, 11) là kết quả em cần lấy

Vậy làm thế nào để chuyển dòng code này thành dạng Function riêng? Và nếu tạo Function riêng thì tốc độ xử lý có nhanh hơn so với ban đầu không?
Em cảm ơn!
 
Lần chỉnh sửa cuối:
"Không cần thiết" chỉ là quan điểm cá nhân của bạn và quan điểm đó hoàn toàn sai lầm.
Chẳng những vậy, nếu có sử dụng biến toàn cục thì việc Dim những biến nội bộ trong Sub là "rất cần thiết".
Nếu có sự trùng hợp tên thì biến nội bộ sẽ được ưu tiên. Và điều này tránh được sự nhầm lẫm đáng tiếc.
Bạn tiết kiệm công gõ, thì phải chi thêm bộ nhớ cho các tham biến toàn cục thôi.
...
Việc "chi thêm bộ nhớ" chưa hẳn là giản dị như vậy.
Theo nguyên tắc thì biến toàn cục dùng bộ nhớ ụ (heap) tức là phần chung cho cả Project; trong khi đó biến nội bộ dùng bộ nhớ ngăn xếp (stack) tức là phần được chia ra riêng cho mỗi Sub/Function.
Khi chạy code, biến nội bộ sẽ được giải phóng sau khi Sub/Function chạy xong (thoát); biến toàn cục vẫn giữ cho đến khi Project chạy hết.
Vì vậy, có ngừoi lập luận rằng như vậy biến nội bộ sẽ tiết kiệm bộ nhớ hơn. Rất tiếc rằng lập luận này không kể đến trường hợp các hàm gọi lồng nhau. Nếu hàm A gọi hàm B, hàm B gọi hàm C thì trong lúc C đang chạy, tất cả các biến nội của B và A vẫn còn nằm trong ngăn xếp, bởi vì A và B chỉ tạm giao phần chay cho C chứ chúng đã thoát đâu (đại khái vậy). Trường hợp này, nếu A, B, và C cùng dùng chung biến toàn cục thì sẽ giảm bộ nhớ.
...Vì file của em cũng nhiều sub, mỗi lần lại phải Dim, em ghét sự lặp lại không cần thiết này anh ạ.
"Không cần thiết" chỉ là quan điểm cá nhân của bạn và quan điểm đó hoàn toàn sai lầm.
Vậy à anh, em cứ nghĩ là như thế quản lý các biến về một mối (@$%@
"Nghĩ" không phải là không tốt. Nhưng vấn đề của bạn là bạn nghĩ nhiều hơn quan sát.
Bước đầu của học là chịu khó quan sát và bắt chước cho thuần thục. Chỉ "nghĩ" khi đã nắm bắt được một số căn bản vững chắc.
Lúc nhỏ học toán thì cô giáo dạy toán cộng trừ nhân chia ra sao cứ việc rắp theo mà làm. Chờ lên cấp 2-3 rồi sẽ tự động học lý do tại sao làm vậy. Và lên Đại học rồi thì có thể tự tìm ra cách làm khác.
 
Upvote 0
Chờ lên cấp 2-3 rồi sẽ tự động học lý do tại sao làm vậy. Và lên Đại học rồi thì có thể tự tìm ra cách làm khác.
Nhiều khi , khi đó hiểu rồi ... học tiếp lại hết hiểu tại sao
 
Upvote 0
Chẳng những vậy, nếu có sử dụng biến toàn cục thì việc Dim những biến nội bộ trong Sub là "rất cần thiết".
Nếu có sự trùng hợp tên thì biến nội bộ sẽ được ưu tiên. Và điều này tránh được sự nhầm lẫm đáng tiếc.

Việc "chi thêm bộ nhớ" chưa hẳn là giản dị như vậy.
Theo nguyên tắc thì biến toàn cục dùng bộ nhớ ụ (heap) tức là phần chung cho cả Project; trong khi đó biến nội bộ dùng bộ nhớ ngăn xếp (stack) tức là phần được chia ra riêng cho mỗi Sub/Function.
Khi chạy code, biến nội bộ sẽ được giải phóng sau khi Sub/Function chạy xong (thoát); biến toàn cục vẫn giữ cho đến khi Project chạy hết.
Vì vậy, có ngừoi lập luận rằng như vậy biến nội bộ sẽ tiết kiệm bộ nhớ hơn. Rất tiếc rằng lập luận này không kể đến trường hợp các hàm gọi lồng nhau. Nếu hàm A gọi hàm B, hàm B gọi hàm C thì trong lúc C đang chạy, tất cả các biến nội của B và A vẫn còn nằm trong ngăn xếp, bởi vì A và B chỉ tạm giao phần chay cho C chứ chúng đã thoát đâu (đại khái vậy). Trường hợp này, nếu A, B, và C cùng dùng chung biến toàn cục thì sẽ giảm bộ nhớ.

"Nghĩ" không phải là không tốt. Nhưng vấn đề của bạn là bạn nghĩ nhiều hơn quan sát.
Bước đầu của học là chịu khó quan sát và bắt chước cho thuần thục. Chỉ "nghĩ" khi đã nắm bắt được một số căn bản vững chắc.
Lúc nhỏ học toán thì cô giáo dạy toán cộng trừ nhân chia ra sao cứ việc rắp theo mà làm. Chờ lên cấp 2-3 rồi sẽ tự động học lý do tại sao làm vậy. Và lên Đại học rồi thì có thể tự tìm ra cách làm khác.
Cảm ơn anh!
 
Upvote 0
Cái này anh làm theo hướng của anh VietMini :). Cảm ơn anh nhé!
Code tôi đã chuẩn hóa để tối ưu đến mức cần thiết, chẳng nhẽ bạn muốn cao siêu hơn, Bác kia chỉ là gói gọn một cơ chế rườm rà, Code của bạn trả lại hai kết quả nên phải dùng Byref, để gửi và nhận, Nếu viết thành Hàm thì kết quả phải là Mảng. Tiêu đề "học" mà chọn Thầy để học thì bạn cứ theo con đường của bạn.
 
Upvote 0
Code tôi đã chuẩn hóa để tối ưu đến mức cần thiết, chẳng nhẽ bạn muốn cao siêu hơn, Bác kia chỉ là gói gọn một cơ chế rườm rà, Code của bạn trả lại hai kết quả nên phải dùng Byref, để gửi và nhận, Nếu viết thành Hàm thì kết quả phải là Mảng. Tiêu đề "học" mà chọn Thầy để học thì bạn cứ theo con đường của bạn.
Dạ không anh tại vì anh bảo xử lý cái 0 kia và theo code ở trên và chỉ em chi tiết hơn thì em thấy nhìn giống của anh VietMini nhất thì em bảo vậy thôi ạ. Em có đọc nhiều bài của anh rồi và em ước bao giờ và có thể để được như anh không. Code của anh là ngắn gọn thì code của anh VietMini là rõ ràng dễ hiểu. Em thích điều đó nhưng đứng trên khía cạnh một người đang học hỏi như em thì em thích cách viết của anh VietMini hơn. Một vấn đề đối với người đã biết thì nó là rất đỗi bình thường nhưng với người chưa biết thì thật sự cách anh VietMini là vừa chỉ vừa dạy. Cảm ơn anh đã quan tâm đến chủ để của em. Chúc anh cuối tuần vui vẻ!
 
Lần chỉnh sửa cuối:
Upvote 0
Dạ không anh tại vì anh bảo xử lý cái 0 kia và theo code ở trên và chỉ em chi tiết hơn thì em thấy nhìn giống của anh VietMini nhất thì em bảo vậy thôi ạ. Em có đọc nhiều bài của anh rồi và em ước bao giờ và có thể để được như anh không. Code của anh là ngắn gọn thì code của anh VietMini là rõ ràng dễ hiểu. Em thích điều đó nhưng đứng trên khía cạnh một người đang học hỏi như em thì em thích cách viết của anh VietMini hơn. Một vấn đề đối với người đã biết thì nó là rất đỗi bình thường nhưng với người chưa biết thì thật sự cách anh VietMini là vừa chỉ vừa dạy. Cảm ơn anh đã quan tâm đến chủ để của em. Chúc anh cuối tuần vui vẻ!

Cho số 0 thứ nhất vào mảng để Idx không phải trừ đi 1, cho số 0 ở mảng thời gian để giải quyết vấn đề kia

Nếu muốn không phải trừ cũng như không phải thêm số 0 thì phải thêm

Option Base 1 - vào đầu Module, nhưng không ai trót dại làm điều này cả, vì lỡ quên thêm option này thì sẽ rắc rối, trừ khi thỏa thuận từ khi bước vào lập trình của bạn là Option Base 1.
Thì lúc đó Index Mảng Array() sẽ bắt đầu từ 1 mà không phải bắt đầu từ 0 nữa.

Vì sao không nên CaseN, CaseD, ... Rõ ràng Sắp xếp của mảng và InStr("NDH...", Ca) đã thỏa thuận trật tự NDH... nó sẽ dư thừa.

Khai báo càng rõ ràng Code sẽ càng rối rắm.
 
Upvote 0
Giải thích thêm cho đoạn code ở bài #8:

Ở đoạn code này, bạn nào để ý sẽ thấy tôi dùng hàm VBA.Array thay vì Array trơn.
Đó là cách tốt nhất để bảo đảm rằng kết quả sẽ là một mảng mà phần tử đầu tiên, nếu có, sẽ mang chỉ số 0. Từ "nếu có" được dùng ở đây là để tránh trường hợp mảng trơn, không có phần tử (zero length array)
Hàm Array trơn hoạt động hơi khác một chút. Việc bắt đầu bằng 0 chỉ là mặc định. Và mặc định này sẽ bị thay đổi nếu đầu module có câu "Option Base ..."
Đôi khi, nếu cần phải đặt phần tử đầu tiên ở chỉ số 1 thì thay vì đặt thêm một phần tử giả ở đầu, người ta sử dụng câu "Option Base 1"
Do đó, trong đoạn code ở bài #8, nếu tôi thực sự không muốn phải điều chỉnh biến caseIdx thì tôi chỉ cần đặt lệnh "Option Base 1" và xóa cái tiền tố "VBA." Khi ấy, các hàm Array sẽ trả về mảng bắt đầu bằng chỉ số 1.

Tiền tố "VBA." buộc VBA phải dùng kiểu dữ liệu thư viện VBA (type library). Và kiểu này thì mảng luôn có chỉ số bắt đầu bằng 0, không bị ảnh hưởng bởi "Option Base ..."

Lưu ý là tôi dùng từ "đoạn code" và nhấn mạnh rằng nó chỉ dùng để chỉ dẫn cách giải quyết, không phải là code cuối cùng đem ra thực nghiệm.

...
Option Base 1 - vào đầu Module, nhưng không ai trót dại làm điều này cả, vì lỡ quên thêm option này thì sẽ rắc rối, trừ khi thỏa thuận từ khi bước vào lập trình của bạn là Option Base 1.
Thì lúc đó Index Mảng Array() sẽ bắt đầu từ 1 mà không phải bắt đầu từ 0 nữa.
...
Mặt khác nếu đang độn một phần tử giả vào đầu mà có ai chơi dại nhét Option Base vào thì hỏng bét.
Nếu đã muốn dùng phương pháp "phần tử độn" thì bắt buộc phải dùng thẳng VBA.Array.
 
Lần chỉnh sửa cuối:
Upvote 0
Cho em hỏi thêm:
Em thêm 1 TimeFrames1 là:
PHP:
CaseN1 = VBA.Array(T8, T17, T22)
CaseH1 = VBA.Array(T8, T17, T22)
CaseX1 = VBA.Array(T6, T14, T22)
CaseY1 = VBA.Array(T14, T22, T22)
CaseZ1 = VBA.Array(T22, T30, T22)
CaseD1 = VBA.Array(T22, T30, T22)
TimeFrames1 = VBA.Array(CaseN1, CaseH1, CaseX1, CaseY1, CaseZ1, CaseD1)
Anh chị có thể gợi ý giúp bóc tách giờ hợp lý giữa giờ Vào Ra với TimeFrames(caseIdx)(0) và TimeFrames(caseIdx)(1) được không?
Cụ thể em muốn lấy số giờ trước TimeFrames(caseIdx)(0) và sau TimeFrames(caseIdx)(1), số giờ thực tế nằm trong khoảng TimeFrames(caseIdx)(0) và TimeFrames(caseIdx)(1) của 6 trường hợp NHXYZD. Cách thông thường dùng nhiều if thì em làm được rồi. Em muốn nâng tầng cao hơn với cái em có thể làm được với mục đích học hỏi. Cảm ơn anh chị!
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom