Chuyên đề giải đáp những thắc mắc về code VBA

Liên hệ QC

maytinhvp01

Thành viên thường trực
Tham gia
27/7/13
Bài viết
390
Được thích
179
Mình muốn nhờ giải thich câu lệnh " If Ran.Cells(d, c) > max Then max = Ran.Cells(d, c) "
trong ví du:
Public Function LonNhat(Ran As Range)
Dim max As Double, v As Integer, d As Integer, c As Integer
max = Ran.Cells(1, 1)
For d = 1 To Ran.Rows.Count
For c = 1 To Ran.Columns.Count
If Ran.Cells(d, c) > max Then max = Ran.Cells(d, c)
Next c
Next d
v = Tim(max, Ran)
LonNhat = max
End Function
-------------------------------------------------------
[INFO1]Thông báo:
Vì topic này:
http://www.giaiphapexcel.com/forum/...ải-thích-các-code-đề-nghị-các-bạn-gửi-vào-đây
đã quá dài nên BQT đóng lại.
Nay tôi mở topic mới với cùng chủ đề: GIẢI THÍCH NHỮNG THẮC MẮC VỀ CODE
Các bạn nếu có nhu cầu giải thích code, vui lòng post tại đây nhé
NDU96081631

[/INFO1]
 
Chỉnh sửa lần cuối bởi điều hành viên:
Vậy mình phải sửa lại như thế nào vậy Bạn.
Bài đã được tự động gộp:


Nhờ các Bạn xem giúp. Mình muốn kết quả như cột N trong sheet DN5. Xin cảm ơn
Bạn xem nhé.Sửa chút it code của bạn.
Mã:
Public Sub GPE_LoC()
Dim Dic As Object, Dic1 As Object, Ma()
Dim sArr(), sArr1(), dArr(), tArr(), TieuDe(), DK As Boolean
Dim I As Long, J As Long, K As Long, N As Long, R As Long
    Set Dic = CreateObject("Scripting.Dictionary")
    sArr = Sheets("Ma").Range("A2:B14").Value
    sArr1 = Sheets("Ma").Range("D2:E9").Value
    For I = 1 To 13
        Dic.Item(sArr(I, 1) & "D") = sArr(I, 2)
    Next I
    For I = 1 To 8
        Dic.Item(sArr1(I, 1) & "T") = sArr1(I, 2)
    Next I
With Sheets("Data")
    sArr = .Range("A2", .Range("A60000").End(xlUp)).Resize(, 44).Value
    R = UBound(sArr)
End With
ReDim dArr(1 To R, 1 To 18)
With Sheets("DN5")
    TieuDe = .Range("AA1:AF3").Value
    tArr = .Range("A10:R10").Value
    For I = 1 To R
        DK = True
        For J = 1 To UBound(TieuDe, 2)
            If TieuDe(3, J) <> Empty Then
                If sArr(I, TieuDe(1, J)) <> TieuDe(3, J) Then
                    DK = False
                    Exit For
                End If
            End If
        Next J
        If DK = True Then
            K = K + 1
            dArr(K, 1) = K
            For J = 2 To UBound(tArr, 2)
                If tArr(1, J) <> Empty Then dArr(K, J) = sArr(I, tArr(1, J))
            Next J
            dArr(K, 10) = Dic.Item(sArr(I, 24) & "D")
            dArr(K, 14) = Dic.Item(sArr(I, 25) & "T")
        End If
    Next I
    .Rows("12:450").Hidden = False
    .Range("A12:R450").ClearContents
    If K Then
        .Range("A12:R12").Resize(K) = dArr
        .Rows(K + 12 & ":450").Hidden = True
    End If
End With
Set Dic = Nothing
End Sub
 
Upvote 0
Rất cảm ơn Bạn đã nhiệt tình giúp đỡ.
Bài đã được tự động gộp:
 
Lần chỉnh sửa cuối:
Upvote 0
Ai có thể giúp tôi sửa lại cái code này với, hay chơi cái trò này nhưng kg biết viết nó như thế nào, xin chân thành cảm ơn và hậu tạ!
 

File đính kèm

Upvote 0
Xin chào các bạn,
OT nhập 3 sử 3 dòng sau trong cửa sổ Immediate để lấy dòng cuối,
Mã:
?Sheet1.Cells(Sheet1.Rows.Count, "E").End(xlUp).Row
?Sheet1.Range("E" & Sheet1.Rows.Count).End(xlUp).Row
?Sheet1.Range("E1048576").End(xlUp).Row

cách viết có hơi khác một chút nhưng đều trả về giá trị giống nhau.
Các bạn chỉ giúp OT - 3 cách viết này khác nhau ở điểm nào được không ạ?
Cảm ơn
 
Upvote 0
3 cái trên: (với ex khác 2003)
- Khác nhau: Cách viết lệnh
- Giống nhau: Đều tìm được ô cuối cùng của 1 cột có chứa dữ và lấy số thứ tự hàng của nó
 
Upvote 0
Xin chào các bạn,
OT nhập 3 sử 3 dòng sau trong cửa sổ Immediate để lấy dòng cuối,
Mã:
?Sheet1.Cells(Sheet1.Rows.Count, "E").End(xlUp).Row
?Sheet1.Range("E" & Sheet1.Rows.Count).End(xlUp).Row
?Sheet1.Range("E1048576").End(xlUp).Row

cách viết có hơi khác một chút nhưng đều trả về giá trị giống nhau.
Các bạn chỉ giúp OT - 3 cách viết này khác nhau ở điểm nào được không ạ?
Cảm ơn
Bạn cứ gõ ?Sheet1.Rows.Count là hiểu
 
Upvote 0
Bạn cứ gõ ?Sheet1.Rows.Count là hiểu
Àh thì ra là vậy:
?Sheet1.Rows.Count
là dùng cho mọi phiên bản office

còn nếu sử dụng Sheet1.Range("E1048576").End(xlUp).Row thì chắc phiên bảo nào có số dòng nhỏ hơn thì sẽ bị lỗi..
hihi OT hiểu là vậy, cảm ơn các bạn!
 
Upvote 0
Àh thì ra là vậy:
?Sheet1.Rows.Count
là dùng cho mọi phiên bản office

còn nếu sử dụng Sheet1.Range("E1048576").End(xlUp).Row thì chắc phiên bảo nào có số dòng nhỏ hơn thì sẽ bị lỗi..
hihi OT hiểu là vậy, cảm ơn các bạn!
Bạn hiểu mỗi cái này là xong.
Mã:
End(xlUp)
 
Upvote 0
Xin chào các bạn,

OT có một thắc mắc nhờ bạn chỉ giúp,tại sao:
Dim arr()
arr = .Range("N8:AG10").Value ---> thì phần tử đầu tiên trong mảng là 1
Còn: ReDim arr1(UBound(arr, 1), 6) ---> thì phần tử đầu tiên trong mảng là 0
mà phải sử dụng: ReDim arr1(1 To UBound(arr, 1), 1 To 6) để phần tử bắt đầu từ 1

Hihi
 
Upvote 0
Đây làm một hàm để so sánh số lớn nhất trong một vùng dữ liệu (Range) nào đó.

Nó căn cứ từ ô đầu tiên của vùng [ Ran.Cells(1, 1) ] làm chuẩn để so sánh với các ô trong vùng đó.

Với câu lệnh này:


If Ran.Cells(d, c) > max Then max = Ran.Cells(d, c)

Với d đại diện cho hàng và c đại diện cho cột, khi vòng lặp chạy lần lượt đến mỗi ô trong Vùng tham chiếu, nếu gặp ô có giá trị lớn hơn giá trị ban đầu max = Ran.Cells(1, 1) thì max sẽ nhận giá trị tại ô đó rồi tiếp tục so sánh sang ô khác, còn không thì nó vẫn giữ giá trị lớn nhất.

=============================
Cái mà tôi không hiểu gì trong hàm đó là cái này:


v = Tim(max, Ran)

Chả biết nó dùng để làm gì nữa!
V= Tim(max,ran)
Theo mình nghĩ function Tim(max,Ran) là 1 hàm riêng biệt được gọi đến
tim(int a,int b)
a>b: max=a
b>a: max=b
return max
Nhưng hàm bên trên mình thấy ko cần thiết phải viết thêm function tim() vì đã gọi đệ quy.
 
Upvote 0
Xin chào các bạn,

OT có một thắc mắc nhờ bạn chỉ giúp,tại sao:
Dim arr()
arr = .Range("N8:AG10").Value ---> thì phần tử đầu tiên trong mảng là 1
Còn: ReDim arr1(UBound(arr, 1), 6) ---> thì phần tử đầu tiên trong mảng là 0
mà phải sử dụng: ReDim arr1(1 To UBound(arr, 1), 1 To 6) để phần tử bắt đầu từ 1

Hihi
Chỗ đỏ đỏ tôi đã từng nói cho bạn.

Tôi đã nhiều lần nói là mọi người ai cũng có một kho kiến thức trong tầm tay nhưng cứ đi tìm ở đâu đâu, không chịu đọc mà cứ đi hỏi.
Trong VBA ở trên góc trên bên phải có 1 trường. Nếu không biết nhập gì thì cứ nhập Array rồi sau khi có môt danh sách thì click vd. vào "Using Arrays". Sẽ có như trong hình. Đọc 3 chỗ tôi đánh dấu thì sẽ không phải hỏi ai nữa.array.JPG
 
Upvote 0
Chỗ đỏ đỏ tôi đã từng nói cho bạn.

Tôi đã nhiều lần nói là mọi người ai cũng có một kho kiến thức trong tầm tay nhưng cứ đi tìm ở đâu đâu, không chịu đọc mà cứ đi hỏi.
Trong VBA ở trên góc trên bên phải có 1 trường. Nếu không biết nhập gì thì cứ nhập Array rồi sau khi có môt danh sách thì click vd. vào "Using Arrays". Sẽ có như trong hình. Đọc 3 chỗ tôi đánh dấu thì sẽ không phải hỏi ai nữa.View attachment 216095
Dạ con chào Bác!
Hình như cái Help của con ở phiên bản office2016 nó hơi khác ạ :
https://docs.microsoft.com/en-us/of...nce/user-interface-help/array-function#syntax

Con sẽ tìm hiểu hiểu thêm ạ, cảm ơn Bác đã chỉ dẫn.
 
Upvote 0
Xin chào các bạn,

OT có một thắc mắc nhờ bạn chỉ giúp,tại sao:
Dim arr()
arr = .Range("N8:AG10").Value ---> thì phần tử đầu tiên trong mảng là 1
Còn: ReDim arr1(UBound(arr, 1), 6) ---> thì phần tử đầu tiên trong mảng là 0
mà phải sử dụng: ReDim arr1(1 To UBound(arr, 1), 1 To 6) để phần tử bắt đầu từ 1

Hihi
Nói cho thật đúng ngôn ngữ mảng thì "phần tử đầu tiên" chả phải là 0 mà cũng chả phải là 1.
0 và 1 là chỉ số để truy phần tử mảng.
Nếu mảng bắt đầu từ 0 thì chỉ số phần tử đầu tiên là 0. Nếu bắt đầu từ 1 thì chỉ số phần tử đầu tiên là 1.
arr(i, j) là biểu thức truy ra phần tử ở chỉ số dòng i và chỉ số cột j của mảng arr.

Dim arr() là lệnh khai báo mảng động, chưa định trước số chiều và độ lớn (phạm vi chỉ số). Lưu ý rằng tôi nói mảng động. Mảng tĩnh nó khác.

ReDim arr(....) là lệnh xác định chiều và phạm vi chỉ số của mảng động. Khi sử dụng ReDim mà không xác định chỉ số dưới (trị của LBound) thì lệnh này mặc định chúng là 0. Mặc định này có thể đổi thành 1 nếu ngay đầu Module có lệnh dẫn trình dịch Option Base 1
Ở đầu mõi Module, trước khi có code khai báo biến và sub, function thì người code có thể nhét một số lệnh dẫn trình dịch. Và Option Base là một trong những lệnh dẫn này (Option Explicit là lệnh dẫn thứ hai)

arr = .Range("N8:AG10").Value là lệnh gán trị của Range vào mảng. Lệnh gán này gọi một hàm kín của đối tượng Range. Hàm này lấy trị Range và tự động xác định chiều cùng phạm vi chỉ số của mảng (có thể coi như nó gọi lệnh Redim), và mặc định chỉ số dưới, tức trị LBound là (1,1)

Chú: khi làm việc với mảng thì phải tìm hiểu cho rõ mỗi hàm của VBA mặc định chỉ số dưới ra sao.
 
Upvote 0
Nói cho thật đúng ngôn ngữ mảng thì "phần tử đầu tiên" chả phải là 0 mà cũng chả phải là 1.
0 và 1 là chỉ số để truy phần tử mảng.
Nếu mảng bắt đầu từ 0 thì chỉ số phần tử đầu tiên là 0. Nếu bắt đầu từ 1 thì chỉ số phần tử đầu tiên là 1.
arr(i, j) là biểu thức truy ra phần tử ở chỉ số dòng i và chỉ số cột j của mảng arr.

Dim arr() là lệnh khai báo mảng động, chưa định trước số chiều và độ lớn (phạm vi chỉ số). Lưu ý rằng tôi nói mảng động. Mảng tĩnh nó khác.

ReDim arr(....) là lệnh xác định chiều và phạm vi chỉ số của mảng động. Khi sử dụng ReDim mà không xác định chỉ số dưới (trị của LBound) thì lệnh này mặc định chúng là 0. Mặc định này có thể đổi thành 1 nếu ngay đầu Module có lệnh dẫn trình dịch Option Base 1
Ở đầu mõi Module, trước khi có code khai báo biến và sub, function thì người code có thể nhét một số lệnh dẫn trình dịch. Và Option Base là một trong những lệnh dẫn này (Option Explicit là lệnh dẫn thứ hai)

arr = .Range("N8:AG10").Value là lệnh gán trị của Range vào mảng. Lệnh gán này gọi một hàm kín của đối tượng Range. Hàm này lấy trị Range và tự động xác định chiều cùng phạm vi chỉ số của mảng (có thể coi như nó gọi lệnh Redim), và mặc định chỉ số dưới, tức trị LBound là (1,1)

Chú: khi làm việc với mảng thì phải tìm hiểu cho rõ mỗi hàm của VBA mặc định chỉ số dưới ra sao.
Bác VetMini,
Về Option Base 1 thì con đã hiểu,còn vấn đề gán từ range vào mảng thì phần tử đầu tiên luôn mặc định là 1,đến ngày hôm nay con mới được biết. :D
Con cảm ơn các Bác đã giải thích và chỉ dẫn ạ.
 
Upvote 0
Dạ con chào Bác!
Hình như cái Help của con ở phiên bản office2016 nó hơi khác ạ :
https://docs.microsoft.com/en-us/of...nce/user-interface-help/array-function#syntax

Con sẽ tìm hiểu hiểu thêm ạ, cảm ơn Bác đã chỉ dẫn.
Có lẽ tôi đã viết rất rõ. Nhập Array là khi bạn chưa biết nhập chi tiết thế nào. Khi ra 1 danh sách thì như hình 1.
array1.JPG
Tôi đã nói rõ là trong danh sách đó thì click vào Using Arrays nhưng bạn lại click vào Array Function (mục đầu tiên trong hình 1).

Nếu bạn cuộn xuống dưới thì bạn sẽ thấy Using Arrays (hình 2) Click vào Declaring Arrays và đọc tiếp. Danh sách có nhiều mục chứ đâu có 1 mục mà bạn.
array2.JPG
 
Upvote 0
Có lẽ tôi đã viết rất rõ. Nhập Array là khi bạn chưa biết nhập chi tiết thế nào. Khi ra 1 danh sách thì như hình 1.
View attachment 216101
Tôi đã nói rõ là trong danh sách đó thì click vào Using Arrays nhưng bạn lại click vào Array Function (mục đầu tiên trong hình 1).

Nếu bạn cuộn xuống dưới thì bạn sẽ thấy Using Arrays (hình 2) Click vào Declaring Arrays và đọc tiếp. Danh sách có nhiều mục chứ đâu có 1 mục mà bạn.
View attachment 216102

Dạ, ý của con là, con đang sử dụng office 2016 nên có thể Help ở dạng Online hơi khác với Help Offline ở các phiên bản Office cũ hơn ạ.
Bác xem đoạn video con thao tác trên máy của con ạ.

Con cảm ơn Bác đã thông tin ạ.
 

File đính kèm

Upvote 0
Dạ, ý của con là, con đang sử dụng office 2016 nên có thể Help ở dạng Online hơi khác với Help Offline ở các phiên bản Office cũ hơn ạ.
Bác xem đoạn video con thao tác trên máy của con ạ.

Con cảm ơn Bác đã thông tin ạ.
Tôi không biết bạn cài Excel thế nào nhưng tôi nghĩ là cũng sẽ có help như của tôi. Không phải phiên bản này giống của tôi và phiên bản khác giống của bạn. Tùy thuộc vào lựa chọn thôi. Tôi không có 2016 nên chỉ đoán thế.

Khi tôi lần đầu tiên dùng help thì cũng của như bạn. Tức khi nhập vd. hichic vào thì có như hình 1. Nhìn thấy "Connected to Office.com"
Sau khi click vào đấy thì như hình 2 và tôi chuyển đánh dấu sang "Show content only from this computer" sau đó đóng cửa sổ. Từ lúc này trở đi thì help sẽ được mở như tôi đã trình bầy, và nhìn thấy lúc này là "Offline" chứ không là "Connected to Office.com"
help1.JPG

help2.JPG

help3.JPG
 
Upvote 0
Web KT

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

Back
Top Bottom