Giúp học viết một Function (1 người xem)

Liên hệ QC

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

tueyennhi

Thành viên tích cực
Tham gia
18/10/10
Bài viết
1,192
Đượ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:
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!
Bài trên của bạn muốn viết Function thì với 5 điều kiện nhé.Ví dụ
Function kiemtra( byaval dk1 as string ...)
Còn về vấn đề tốc độ sử lý thì mình nghĩ code nó sẽ nhanh hơn. Code nó sẽ sử lý nhanh hơn.
 
Upvote 0
Bạn tham khảo cách này xem:
PHP:
Function VaoRa(Ca As String, Vao As Double, Ra As Double, Optional GioVao As Boolean = True)
Const T06 As Double = #6:00:00 AM#:                     Const T08 As Double = #8:00:00 AM#
Const T21 As Double = #9:00:00 PM#:                      Const T20 As Double = #8:00:00 PM#
Const T14 As Double = #2:00:00 PM#:                      Const T15 As Double = #3:00:00 PM#
Const T22 As Double = #10:00:00 PM#:                      Const T31 As Double = #12:00:00 PM#
Const T17 As Double = #5:00:00 PM#:                      Const T32 As Double = #11:00:00 PM#   '?? '
Const T18 As Double = #6:00:00 PM#:                       Const T33 As Double = #10:00:00 PM#  '?? '
' . . . . . . .         '
Select Case Ca
Case "N"
    If Vao > T6 And Vao <= T8 Then
        If Ra < T21 And Ra >= T20 Then
            If GioVao Then
                VaoRa = T8
            Else
                VaoRa = T20
            End If
        End If
    End If
Case Else
    ' . . . . .         '
End Select
End Function
 
Upvote 0
VBA là loại ngôn ngữ cũ. Nó có sự phân biệt giữa Sub và Function.

Ngừoi ta viết Function (hàm) khi cần nó trả về một cái gì đó. Trong ví dụ của bạn thì bạn cần nó trả về cái gì?

Cách học của bạn loạn xạ quá rồi. Bạn cần tìm tài liệu VBA mà đi trở lại từ căn bản.
 
Upvote 0
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
...
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

Thấy cái đề tài này hay hay nên tôi cũng muốn tham khảo thêm vụ chấm công này của bạn.
Tôi dịch ra như thế này, không biết tôi có hiểu đúng ý của code này của bạn không nhé. Lấy ví dụ ca "N" thôi.
Nếu giờ bấm Vào nằm trong khoảng 6 - 8h sáng và Ra trong khoảng 21h đổ lại thì sẽ lấy tham số của ca 8 - 20?
Vậy:
- Còn Select case "N" để làm gì vì đã xác định nhân viên đó thuộc ca "N" là ca 8 -20h?
- Nếu nhân viên bấm Vào 8h 5', 8h 10'...thì tính vô trường hợp nào?
Không trong lĩnh vực của bạn nên chưa hiểu lắm :)
 
Upvote 0
Thấy cái đề tài này hay hay nên tôi cũng muốn tham khảo thêm vụ chấm công này của bạn.
Ông chủ thớt có vụ chấm công kéo dài từ 3-4 năm trước đây tới bài này đó anh.
Ổng thấy VBA hay hay... mà hay thật nên nhảy vào. Kêu ổng đọc lý thuyết, đưa tài liệu sẵn đủ kiểu.. nhưng ổng không chịu đọc, mà chỉ thích có kết quả ngay thôi. @@
----
Ai muốn ra tay... thì phải quay về quá khứ và bắt đầu từ mấy năm trước ấy.
 
Upvote 0
Hehe.. :) . Tại cái vấn đề chấm công này nó điên đầu lắm, mỗi Cty mỗi vẽ nên cũng muốn tìm hiểu thêm loại hình ca làm việc hơn 12 tiếng này.
Mình chỉ làm cái bảng ca cho nhân viên nhà hàng nhỏ xíu thôi mà cũng rối rồi, phải cung cấp cả đống tham số mới tính được và cũng chưa làm tự động hoàn toàn mà vẫn phải xử lý thủ công (nhập tay) một số công đoạn điều chỉnh giờ công một số trường hợp ngoại lệ, đặc thù, máy chấm sai, máy bị lỗi v.v.. cho từng nhân viên.

223807
 
Lần chỉnh sửa cuối:
Upvote 0
Mấy cái Cases làm việc đại khái như nhau. Đáng lẽ phải làm bằng mảng.

CaseN = VBA.Array(T6, T8, T20, T21)
CaseD = VBA.Array(T18, T20, T32, T33)
CaseH = ...
...
timeFrames = VBA.Array(CaseN, CaseD, CaseH, CaseX, CaseY, CaseZ)
...
caseIdx = InStr("NDHXYZ", Ca)
If caseIdx Then
caseIdx = caseIdx -1 ' adjust index to begin at 0
If Vao > timeFrames(caseIdx)(1) And Vao <= timeFrames(caseIdx)(2) _
And Ra >= timeFrames(caseIdx)(3) And Ra < timeFrames(caseIdx)(4) Then
Arr(j, 10) = timeFrames(caseIdx)(2)
Arr(j, 11) = timeFrames(caseIdx)(3)
End If
End If
 
Upvote 0
Các Bác đã giúp thì giúp bạn ấy cho trót cái đoạn "nhô ra một cách lạ kì"
Có vẻ như ví dụ không đồng bộ hoặc theo ý của bạn ấy là vậy.

----------------------------------------------
PHP:
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
-------------------
Mình "ăn trộm code" của các Bác ở trên chứ không biết nhiều về VBA. Chủ yếu đăng bài kiếm "Like, ..."
Giải quyết luôn cái trường hợp "Hài hước kia" bằng cách cho số 0 vào.
-------------------

PHP:
Private Sub test_ThoiGianGiaoCa()
  Dim Ca$, Vao#, Ra#
  Ca = "N": Vao = #5:59:00 AM#: Ra = #8:05:00 PM#
  Call ThoiGianGiaoCa(Ca, Vao, Ra)
  Debug.Print Vao, Ra
End Sub
Sub ThoiGianGiaoCa(ByVal Ca$, ByRef Vao#, ByRef Ra#)
  Dim T, Idx%
  Const T06 = #6:00:00 AM#:   Const T08 = #8:00:00 AM#
  Const T21 = #9:00:00 PM#:   Const T20 = #8:00:00 PM#
  Const T14 = #2:00:00 PM#:   Const T15 = #3:00:00 PM#
  Const T22 = #10:00:00 PM#:  Const T31 = #12:00:00 PM#
  Const T17 = #5:00:00 PM#:   Const T32 = #11:00:00 PM#
  Const T18 = #6:00:00 PM#:   Const T33 = #10:00:00 PM#
  T = Array(0, Array(T06, T08, T20, T21), _
            Array(T18, T20, T32, T33), _
            Array(T06, T08, T17, T18), _
            Array(0, T06, T14, T15), _
            Array(T10, T14, T22, T23), _
            Array(T20, T22, T30, T31))
  Idx = InStr("NDHXYZ", Ca)
  If Idx Then
    If Vao > T(Idx)(0) And Vao <= T(Idx)(1) _
    And Ra >= T(Idx)(2) And Ra < T(Idx)(3) Then
      Vao = T(Idx)(1): Ra = T(Idx)(2): Goto Ends
    End If
  End If
  Vao = 0 : Ra = 0
Ends: Erase T
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Muốn viết để xài được thì cần biết/thấy qui chế chấm công của CQ chủ bài đăng;
Còn trong quá trình học viết hàm thì chỉ nên gợi ý thôi & nên viết 1 cách đơn giản sao cho dễ hiểu với người chập chững!
 
Upvote 0
VBA là loại ngôn ngữ cũ. Nó có sự phân biệt giữa Sub và Function.

Ngừoi ta viết Function (hàm) khi cần nó trả về một cái gì đó. Trong ví dụ của bạn thì bạn cần nó trả về cái gì?

Cách học của bạn loạn xạ quá rồi. Bạn cần tìm tài liệu VBA mà đi trở lại từ căn bản.
Vâng, anh nói đúng. Em ngẫu hứng nghĩ cái gì thì tìm hiểu cái đó chứ không học bài bản. Trong ví dụ của em mảng Arr(i,10) và Arr(i,11) là kết quả em cần lấy. Vì là dạng trả kết quả mảng nên em không biết cách làm. Nếu viết theo cách trả về kết quả từng mảng 1 thì vòng lặp và điều kiện xét của em x2 lần không cần thiết nên hỏi anh chị xem cách viết nào hợp lý nhất.
Bài đã được tự động gộp:

Thấy cái đề tài này hay hay nên tôi cũng muốn tham khảo thêm vụ chấm công này của bạn.
Tôi dịch ra như thế này, không biết tôi có hiểu đúng ý của code này của bạn không nhé. Lấy ví dụ ca "N" thôi.
Nếu giờ bấm Vào nằm trong khoảng 6 - 8h sáng và Ra trong khoảng 21h đổ lại thì sẽ lấy tham số của ca 8 - 20?
Vậy:
- Còn Select case "N" để làm gì vì đã xác định nhân viên đó thuộc ca "N" là ca 8 -20h?
- Nếu nhân viên bấm Vào 8h 5', 8h 10'...thì tính vô trường hợp nào?
Không trong lĩnh vực của bạn nên chưa hiểu lắm :)
Vâng anh các trường hợp không trong điều kiện trên thì buộc em phải chấm tay ở cột riêng. Trường hợp anh giả sử thì nó sẽ theo quy luật tiến lên 15p nghĩa là từ trên 1 đến 15 thì đều tính tròn 15. Ví dụ 8h5p -> 8h15'. 8h31' --> 8h45'
Bài đã được tự động gộp:

Ông chủ thớt có vụ chấm công kéo dài từ 3-4 năm trước đây tới bài này đó anh.
Ổng thấy VBA hay hay... mà hay thật nên nhảy vào. Kêu ổng đọc lý thuyết, đưa tài liệu sẵn đủ kiểu.. nhưng ổng không chịu đọc, mà chỉ thích có kết quả ngay thôi. @@
----
Ai muốn ra tay... thì phải quay về quá khứ và bắt đầu từ mấy năm trước ấy.
Thực ra code từ đó đến nay em vẫn dùng và thay đổi dần dần cho tốt hơn. Mỗi lần biết hơn một chút thì em thấy code có thể viết tốt hơn một chút. Và chủ đề này là một ví dụ như vậy. Đúng là em chỉ quan tâm kết quả, ví dụ động đến vấn đề nào đó thì em sẽ tìm trên mạng rồi lấy code đó tham khảo và chỉnh sửa theo đúng hoàn cảnh của mình.
Bài đã được tự động gộp:

Mấy cái Cases làm việc đại khái như nhau. Đáng lẽ phải làm bằng mảng.

CaseN = VBA.Array(T6, T8, T20, T21)
CaseD = VBA.Array(T18, T20, T32, T33)
CaseH = ...
...
timeFrames = VBA.Array(CaseN, CaseD, CaseH, CaseX, CaseY, CaseZ)
...
caseIdx = InStr("NDHXYZ", Ca)
If caseIdx Then
caseIdx = caseIdx -1 ' adjust index to begin at 0
If Vao > timeFrames(caseIdx)(1) And Vao <= timeFrames(caseIdx)(2) _
And Ra >= timeFrames(caseIdx)(3) And Ra < timeFrames(caseIdx)(4) Then
Arr(j, 10) = timeFrames(caseIdx)(2)
Arr(j, 11) = timeFrames(caseIdx)(3)
End If
End If
Để em xem có xoay sở được không nhé, cảm ơn anh!
 
Lần chỉnh sửa cuối:
Upvote 0
Các Bác đã giúp thì giúp bạn ấy cho trót cái đoạn "nhô ra một cách lạ kì"
Có vẻ như ví dụ không đồng bộ hoặc theo ý của bạn ấy là vậy.

----------------------------------------------
PHP:
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
-------------------
Mình "ăn trộm code" của các Bác ở trên chứ không biết nhiều về VBA. Chủ yếu đăng bài kiếm "Like, ..."
Giải quyết luôn cái trường hợp "Hài hước kia" bằng cách cho số 0 vào.
-------------------

PHP:
Private Sub test_ThoiGianGiaoCa()
  Dim Ca$, Vao#, Ra#
  Ca = "N": Vao = #5:59:00 AM#: Ra = #8:05:00 PM#
  Call ThoiGianGiaoCa(Ca, Vao, Ra)
  Debug.Print Vao, Ra
End Sub
Sub ThoiGianGiaoCa(ByVal Ca$, ByRef Vao#, ByRef Ra#)
  Dim T, Idx%
  Const T06 = #6:00:00 AM#:   Const T08 = #8:00:00 AM#
  Const T21 = #9:00:00 PM#:   Const T20 = #8:00:00 PM#
  Const T14 = #2:00:00 PM#:   Const T15 = #3:00:00 PM#
  Const T22 = #10:00:00 PM#:  Const T31 = #12:00:00 PM#
  Const T17 = #5:00:00 PM#:   Const T32 = #11:00:00 PM#
  Const T18 = #6:00:00 PM#:   Const T33 = #10:00:00 PM#
  T = Array(0, Array(T06, T08, T20, T21), _
            Array(T18, T20, T32, T33), _
            Array(T06, T08, T17, T18), _
            Array(0, T06, T14, T15), _
            Array(T10, T14, T22, T23), _
            Array(T20, T22, T30, T31))
  Idx = InStr("NDHXYZ", Ca)
  If Idx Then
    If Vao > T(Idx)(1) And Vao <= T(Idx)(2) _
    And Ra >= T(Idx)(3) And Ra < T(Idx)(4) Then
      Vao = T(Idx)(2): Ra = T(Idx)(3): Goto Ends
    End If
  End If
  Vao = 0 : Ra = 0
Ends: Erase T
End Sub
Cái này anh làm theo hướng của anh VietMini :). Cảm ơn anh nhé!
 
Upvote 0
... Trong ví dụ của em mảng Arr(i,10) và Arr(i,11) là kết quả em cần lấy. Vì là dạng trả kết quả mảng nên em không biết cách làm. ...
Hàm chỉ trả về được một trị hoặc một đối tượng. Nhu cầu của bạn là cần chép vào 2 biến Arr(i,10) và Arr(i,11). Do đó bạn chỉ có thể nạp 2 biến ấy vào tham số dạng ByRef để Sub/Hàm sử lý. Trường hợp của bạn thì 2 biến ấy là phần tử của 1 mảng cho nên có thể nạp mảng và chỉ số. Trường hợp này cũng vì phải nạp nhiều tham "cố định" (mảng Arr, các trị T's) quá cho nên có thể dùng biến toàn cục để giảm thiểu số tham phải nạp. Tôi chỉ nói vậy cho các bạn muốn học thêm thôi chứ nếu trình độ của bạn như thế thì quản lý biến toàn cục hơi mệt.

Trường hợp bạn muốn tìm hiểu cách viết hàm trả về nhiều hơn 1 trị thì có các cách sau:
1. lập 1 Type hoặc Object chứa các trị ấy. Như vậy hàm chỉ cần trả về biến với Type trên hoặc đối tượng đã lập.
2. đơn giản hơn, cho hàm trả về một mảng. Mỗi phần tử của mảng là một trị cần trả về.
Bạn có thể tham khảo ví dụ tôi đã dùng hàm trả về 1 trị, hàm trả về 2 trị (mảng 2 phần tử), và Sub (không trả về gì cả) ở đây

 
Upvote 0
Hàm chỉ trả về được một trị hoặc một đối tượng. Nhu cầu của bạn là cần chép vào 2 biến Arr(i,10) và Arr(i,11). Do đó bạn chỉ có thể nạp 2 biến ấy vào tham số dạng ByRef để Sub/Hàm sử lý. Trường hợp của bạn thì 2 biến ấy là phần tử của 1 mảng cho nên có thể nạp mảng và chỉ số. Trường hợp này cũng vì phải nạp nhiều tham "cố định" (mảng Arr, các trị T's) quá cho nên có thể dùng biến toàn cục để giảm thiểu số tham phải nạp. Tôi chỉ nói vậy cho các bạn muốn học thêm thôi chứ nếu trình độ của bạn như thế thì quản lý biến toàn cục hơi mệt.

Trường hợp bạn muốn tìm hiểu cách viết hàm trả về nhiều hơn 1 trị thì có các cách sau:
1. lập 1 Type hoặc Object chứa các trị ấy. Như vậy hàm chỉ cần trả về biến với Type trên hoặc đối tượng đã lập.
2. đơn giản hơn, cho hàm trả về một mảng. Mỗi phần tử của mảng là một trị cần trả về.
Bạn có thể tham khảo ví dụ tôi đã dùng hàm trả về 1 trị, hàm trả về 2 trị (mảng 2 phần tử), và Sub (không trả về gì cả) ở đây

Vâng em cảm ơn anh! Em cũng đang sử dụng biến toàn cục rồi ạ.

Chỗ anh chỉ em ở trên em đã viết thành như này và đã chạy ngon lành rồi anh nhé. Em thích cách anh viết code, rõ ràng mạch lạc.

PHP:
        CaseN = VBA.Array(T6, T8, T20, T21)
        CaseD = VBA.Array(T18, T20, T32, T33)
        CaseH = VBA.Array(T6, T8, T17, T18)
        CaseX = VBA.Array(0, T6, T14, T15)
        CaseY = VBA.Array(T10, T14, T22, T23)
        CaseZ = VBA.Array(T20, T22, T30, T31)
    
        TimeFrames = VBA.Array(CaseN, CaseD, CaseH, CaseX, CaseY, CaseZ)

        caseIdx = InStr("NDHXYZ", Ca)
        If caseIdx Then
                   caseIdx = caseIdx - 1
         If Vao > TimeFrames(caseIdx)(0) And Vao <= TimeFrames(caseIdx)(1),_
         And Ra >= TimeFrames(caseIdx)(2) And Ra < TimeFrames(caseIdx)(3) Then
                   Arr(j, 10) = TimeFrames(caseIdx)(1)
                   Arr(j, 11) = TimeFrames(caseIdx)(2)
         End If
         End If

Nhân tiện anh nói về biến toàn cục cho em hỏi thêm ngoài luồng:
Em có nên để biến toàn cục như này không: Public Rws As Long, R As Long, I As Long, j As Long, k As Long, h As Long
Hiện em đang sử dụng, mỗi sub lại cần call một sub để reset các biến này về 0 anh ạ, hơi chuối.
 
Lần chỉnh sửa cuối:
Upvote 0
Nhân tiện anh nói về biến toàn cục cho em hỏi thêm ngoài luồng:
Em có nên để biến toàn cục như này không: Public Rws As Long, R As Long, I As Long, j As Long, k As Long, h As Long
Hiện em đang sử dụng, mỗi sub lại cần call một sub để reset các biến này về 0 anh ạ, hơi chuối.
Vậy thì bạn dùng biến toàn cục chi cho cực thân :D
 
Upvote 0
Cảm ơn anh, người đặt nền móng đầu tiên cho em về VBA :)
Bạn tham khảo cách này xem:
PHP:
Function VaoRa(Ca As String, Vao As Double, Ra As Double, Optional GioVao As Boolean = True)
Const T06 As Double = #6:00:00 AM#:                     Const T08 As Double = #8:00:00 AM#
Const T21 As Double = #9:00:00 PM#:                      Const T20 As Double = #8:00:00 PM#
Const T14 As Double = #2:00:00 PM#:                      Const T15 As Double = #3:00:00 PM#
Const T22 As Double = #10:00:00 PM#:                      Const T31 As Double = #12:00:00 PM#
Const T17 As Double = #5:00:00 PM#:                      Const T32 As Double = #11:00:00 PM#   '?? '
Const T18 As Double = #6:00:00 PM#:                       Const T33 As Double = #10:00:00 PM#  '?? '
' . . . . . . .         '
Select Case Ca
Case "N"
    If Vao > T6 And Vao <= T8 Then
        If Ra < T21 And Ra >= T20 Then
            If GioVao Then
                VaoRa = T8
            Else
                VaoRa = T20
            End If
        End If
    End If
Case Else
    ' . . . . .         '
End Select
End Function
Bài đã được tự động gộp:

Vậy thì bạn dùng biến toàn cục chi cho cực thân :D
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 ạ.
 
Upvote 0
Upvote 0
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 ạ.
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.
Mình khuyên nên khai báo toàn cục chỉ khi tham biến đó có xài trong hầu hết các macro & cần lưu trong nơi nào đó để xài lại trị của nó ở lần chạy macro khác.
Tham biến để ghi nhận dòng dữ liệu trong ListBox,
. . . . .
Còn chỉ vì ghét sự lặp lại khái báo biến mà đưa nó thành toàn cục là hoàn toàn không nên.
 
Upvote 0
Mục đích chính của biến toàn cục là để các Sub/Function chia sẻ thông tin với nhau. Nếu không cần chia sẻ thì không cần dùng biến toàn cục.
 
Upvote 0
"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 (@$%@
Bài đã được tự động gộp:

Vậy là em hiểu sai về biến toàn cục rồi :(
Mục đích chính của biến toàn cục là để các Sub/Function chia sẻ thông tin với nhau. Nếu không cần chia sẻ thì không cần dùng biến toàn cục.
 
Lần chỉnh sửa cuối:
Upvote 0
"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

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

Back
Top Bottom