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:
Dear A/c có cách nào giúp tốc độ code phia dưới nhanh hơn dc ko , nhờ a/c giúp
Code dưới là ghi dữ liệu từ textbox trên userform vào sheet

Mã:
Private Sub CommandButton5_Click()

Dim lastrow As Long
Dim i As Long
With Sheets("Pak_in")
For i = 1 To 115 Step 6
lastrow = Sheets("Pak_in").Cells(Rows.Count, "D").End(xlUp).Row + 1
If Controls("TextBox" & i) = "" Then Exit Sub
.Range("D" & lastrow) = Controls("TextBox" & i)
.Range("E" & lastrow) = Controls("TextBox" & i + 1)
.Range("F" & lastrow) = Controls("TextBox" & i + 2)
.Range("G" & lastrow) = Controls("TextBox" & i + 3)
.Range("H" & lastrow) = Controls("TextBox" & i + 4).Value
.Range("I" & lastrow) = Controls("TextBox" & i + 5)

Controls("TextBox" & i) = ""
Controls("TextBox" & i + 1) = ""
Controls("TextBox" & i + 2) = ""
Controls("TextBox" & i + 3) = ""
Controls("TextBox" & i + 4) = ""
Controls("TextBox" & i + 5) = ""
Next i
End With
End Sub
Cách thì có nhưng nhìn thấy file mới viết được code.
 
Upvote 0
Code bên dưới mình khai báo thêm Dic1 nhưng bị lỗi
Mã:
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")
    Set Dic1 = 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)) = sArr(I, 2)
        Dic1.Item(sArr1(I, 1)) = sArr1(I, 2)
    Next I
Các Bạn chỉ giúp cách sửa lại để không bị lỗi.
Xin cảm ơn.
 
Upvote 0
Code bên dưới mình khai báo thêm Dic1 nhưng bị lỗi
Mã:
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")
    Set Dic1 = CreateObject("Scripting.Dictionary")
    sArr = Sheets("Ma").Range("A2:B14").Value
    [CODE]sArr1 = Sheets("Ma").Range("D2:E14").Value

For I = 1 To 13
Dic.Item(sArr(I, 1)) = sArr(I, 2)
Dic1.Item(sArr1(I, 1)) = sArr1(I, 2)
Next I[/CODE]
Các Bạn chỉ giúp cách sửa lại để không bị lỗi.
Xin cảm ơn.
Lỗi dòng lệnh này.
Mã:
   Dic1.Item(sArr1(I, 1)) = sArr1(I, 2)
Không liên quan gì đến DIC1 cả.Cái này gặp phải vấn đề là mảng nó không tồn tại.
Bạn sửa dòng này thành
Mã:
sArr1 = Sheets("Ma").Range("D2:E14").Value
 
Upvote 0
Lỗi dòng lệnh này.
Mã:
   Dic1.Item(sArr1(I, 1)) = sArr1(I, 2)
Không liên quan gì đến DIC1 cả.Cái này gặp phải vấn đề là mảng nó không tồn tại.
Bạn sửa dòng này thành
Mã:
sArr1 = Sheets("Ma").Range("D2:E14").Value
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:

Lỗi dòng lệnh này.
Mã:
   Dic1.Item(sArr1(I, 1)) = sArr1(I, 2)
Không liên quan gì đến DIC1 cả.Cái này gặp phải vấn đề là mảng nó không tồn tại.
Bạn sửa dòng này thành
Mã:
sArr1 = Sheets("Ma").Range("D2:E14").Value
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
 

File đính kèm

  • PhoCap - Copy.xlsb
    76.6 KB · Đọc: 6
Lần chỉnh sửa cuối:
Upvote 0
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

  • Tinhtoande.xlsm
    1.4 MB · Đọc: 18
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
Web KT
Back
Top Bottom