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:
Nhờ anh chị giùm em cái này với ạ . Em viết một cái hàm function để tính giá trị SPL cho bài này. Do em phải chạy rất nhiều trường hợp, mà cứ mỗi lần chạy trường hợp nào là em phải viết lại cách tính này, chỉ đổi giá trị i và các cột tương ứng thôi. Giờ em muốn viết một hàm bao gồm cho tất cả các trường hợp ạ. Mong anh chị giúp đỡ

For i = 18 To 31

frequency = Cells(i, 1)
lambda = sv / frequency
Fresnel_number = 2# * delta / lambda
Call Attenuation_by_Diffraction(Fresnel_number, Att_Diff)

Cells(i, 3) = Cells(i, 2).Value + Cells(12, 2).Value
Cells(i, 4) = Fresnel_number
Cells(i, 5) = Att_Diff

SPL = Att_Diff + Cells(i, 3).Value

Cells(i, 6) = SPL

Next i

 
Upvote 0
Em viết một cái hàm function để tính giá trị SPL cho bài này. Do em phải chạy rất nhiều trường hợp, mà cứ mỗi lần chạy trường hợp nào là em phải viết lại cách tính này, chỉ đổi giá trị i và các cột tương ứng thôi. Giờ em muốn viết một hàm bao gồm cho tất cả các trường hợp ạ. Mong anh chị giúp đỡ

Giống như bạn bơi đã ra giữa sông, thấy đuối nên kêu cứu thì fải
Có lẽ ta fải quay lại từ đầu & mô tả công việc lại 1 cách rõ ràng mới được;
Mà bạn có lẫn lộn giữa 1 Sub hay 1 hàm (Function) không đấy?
 
Upvote 0
Giống như bạn bơi đã ra giữa sông, thấy đuối nên kêu cứu thì fải
Có lẽ ta fải quay lại từ đầu & mô tả công việc lại 1 cách rõ ràng mới được;
Mà bạn có lẫn lộn giữa 1 Sub hay 1 hàm (Function) không đấy?

Chính xác là em đang bị mắc giữa dòng đây bác ạ. -\\/.
Em đang viết sub để tính giá trị SPL (các cột được tô xanh) cho 4 trường hợp. Cách tính thì y chang giống nhau mà chỉ khác địa chỉ các ô thôi. Em đang nghĩ đến việc viết một cái funtion để ap dụng cho cả 4 trường hợp. Đặc biết là đoạn code ở trên, làm sao để đoạn code này không phải lặp lại dài dòng cho cả mấy trường hợp như vậy ạ. Ý là làm một cái funtion cho đoạn sub ngắn lại thì tốt quá
Bác quăng phao cho em với ạ.

Em gửi file đính kèm bác mở ra là hiểu liền ạ .
 

File đính kèm

  • SPL.xlsm
    29.2 KB · Đọc: 6
Lần chỉnh sửa cuối:
Upvote 0
Nhờ anh chị giùm em cái này với ạ . Em viết một cái hàm function để tính giá trị SPL cho bài này. Do em phải chạy rất nhiều trường hợp, mà cứ mỗi lần chạy trường hợp nào là em phải viết lại cách tính này, chỉ đổi giá trị i và các cột tương ứng thôi. Giờ em muốn viết một hàm bao gồm cho tất cả các trường hợp ạ. Mong anh chị giúp đỡ

For i = 18 To 31

frequency = Cells(i, 1)
lambda = sv / frequency
Fresnel_number = 2# * delta / lambda
Call Attenuation_by_Diffraction(Fresnel_number, Att_Diff)

Cells(i, 3) = Cells(i, 2).Value + Cells(12, 2).Value
Cells(i, 4) = Fresnel_number
Cells(i, 5) = Att_Diff

SPL = Att_Diff + Cells(i, 3).Value

Cells(i, 6) = SPL

Next i


Với code trên thì không thể làm được. Trong code bạn có lấy giá trị của ô [12,2]. Nếu đổi giá trị i (18-31) sang cái gì đó thì phải biết nó có ảnh hưởng đến [12,2] hay không.
 
Upvote 0
Đó là kết quả đúng mà, fải vậy không?
Những ô mà macro tô màu ở cột là những ô chứa giá trị không được tìm thấy ở trang bên & giá trị ô màu này cũng được macro lần lượt ghi ở cột [D], bắt đầu từ [D2];
Còn [D1] để ghi lại thời gian tiêu tốn cho macro.

Nhưng nên bỏ macro vô module1

Cảm ơn bạn đã giúp đỡ nhưng mình muốn cho nó tô màu và tự chèn vào 1 sheet khác 2 sheet đó để cho mọi người trong ca dễ hiểu hơn đc ko hả bạn ? Với lại với 4000 dòng thì liệu có bị chậm ko hả bạn ??
 
Upvote 0
Với code trên thì không thể làm được. Trong code bạn có lấy giá trị của ô [12,2]. Nếu đổi giá trị i (18-31) sang cái gì đó thì phải biết nó có ảnh hưởng đến [12,2] hay không.

Vậy ví dụ em bỏ luôn cái giá trị của ô [12,2] thì có viết được function không hả bác.
 
Upvote 0
function xyz(byval r1 as long, byval r2 as long) as double
...
for i = r1 to r2
...
next
...

Lưu y: code này thay đổi giá trị các cells trong sheet nên function chỉ có thể dùng sub khác để gọi, không thể làm hàm dùng trong worksheet.
 
Upvote 0
Cảm ơn bạn đã giúp, (2) mình muốn cho nó tô màu và tự chèn vào 1 sheet khác 2 sheet đó để cho mọi người trong ca dễ hiểu hơn đc ko hả bạn ?
(1) Với lại với 4000 dòng thì liệu có bị chậm ko hả bạn ??

(1) Nhanh chậm còn tùy thuộc cấu hình, số liệu & cấu trúc các trang tính của bạn;
Trong lệnh gần cuối macro, nó có ghi thời gian cần để nó hoàn tất mà. Căn cứ vô đó, nếu thấy ì ạch thì kêu lên; Sẽ có người tới cứu bạn khỏi sa lầy.

(2) Muốn nó ghi vào trang tính khác thì thêm tên cúng cơm của trang tính cần ghi vô dòng lệnh này:
Mã:
[FONT=Courier New][COLOR=#007700][[/COLOR][COLOR=#0000bb]d65500[/COLOR][COLOR=#007700]].[/COLOR][COLOR=#0000bb]End[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]xlUp[/COLOR][COLOR=#007700]).[/COLOR][COLOR=#0000bb]Offset[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]1[/COLOR][COLOR=#007700]).[/COLOR][COLOR=#0000bb]Value [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]Cls[/COLOR][COLOR=#007700].[/COLOR][/FONT][COLOR=#0000bb][FONT=Courier New]Value [/FONT][/COLOR]

Ví dụ
PHP:
 Sheets("KQua").[d65500].End(xlUp).Offset(1).Value = Cls.Value

Chúc vui!

 
Upvote 0
Chính xác là em đang viết sub để tính giá trị SPL (các cột được tô xanh) cho 4 trường hợp. Cách tính thì y chang giống nhau mà chỉ khác địa chỉ các ô thôi. Em đang nghĩ đến việc viết một cái funtion để ap dụng cho cả 4 trường hợp.
Ý là làm một cái funtion cho đoạn sub ngắn lại thì tốt quá
Bác quăng phao cho em với ạ.
Em gửi file đính kèm bác mở ra là hiểu liền ạ .
Mình xin bạn nêu rõ ràng, rành mạch cái Sub lần nữa 1 cách tường minh:
PHP:
For i = 18 To 31
  frequency = Cells(i, 1)   
  lambda = sv / frequency   'SV này lấy ở đâu?'
  Fresnel_number = 2# * delta / lambda  ' Delta lấy từ đâu?'
 Call Attenuation_by_Diffraction(Fresnel_number, Att_Diff)  '. Tại (*) & tham biến sau lấy từ đâu'
 Cells(i, 3) = Cells(i, 2).Value + Cells(12, 2).Value
 Cells(i, 4) = Fresnel_number
 Cells(i, 5) = Att_Diff
SPL = Att_Diff + Cells(i, 3).Value

Cells(i, 6) = SPL
Next i

(*)
Mã:
Sub Attenuation_by_Diffraction(n As Double, dL As Double)
 If n >= 1# Then dL = -10# * Log10(n / 5#) - 20#
 If n < 1# And n >= 0.1 Then dL = -4.97 * Log10(n) - 13.01
 If n < 0.1 And n >= 0.01 Then dL = -2.09 * Log10(n) - 10.12
 If Abs(n) < 0.01 Then dL = -77# * n - 5.17
 If n <= -0.01 And n > -0.3 Then dL = 10# * Log10(0.33 / (cuberoot(n) + 1#))
 If n <= -0.3 Then dL = 0#
End Sub
 
Upvote 0
Đoạn code dưới đây đang chạy lọc ngày duy nhất có sắp xếp theo thứ tự tăng dần. Lọc dữ liệu ngày từ cột A của sheet Data, sau đó lấy kết quả cho sang cột A của sheet Chart và tính tổng giá trị của cột B sheet Data rồi cho sang cột B sheet Chart. Nó chạy rất tốt rồi. Do có 1 sheet khác em cũng dùng code này nhưng ko cần phần tính tổng. Nên Em muốn nhờ A/C giúp Em sửa code. Bỏ phần tính tổng, chỉ giữ lại code lọc ngày duy nhất có sắp xếp tăng dần. Cám ơn A/C nhiều!


Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$C$1" Then
Dim sArr(), I&, J&, Dic As Object, dArr, K&, Tmp
With Sheet1
    sArr = .Range(.[A2], .[A65000].End(3)).Resize(, 2).Value
End With
ReDim dArr(1 To UBound(sArr), 1 To UBound(sArr, 2))
Set Dic = CreateObject("Scripting.Dictionary")
With Dic
    For I = 1 To UBound(sArr, 1)
        Tmp = sArr(I, 1)
        If Not .Exists(Tmp) Then
            K = K + 1
            .Add Tmp, K
            For J = 1 To UBound(sArr, 2)
                dArr(K, J) = sArr(I, J)
            Next J
        Else
            dArr(.Item(Tmp), 2) = dArr(.Item(Tmp), 2) + sArr(I, 2)
        End If
    Next I
End With
With Sheet3
        .Range("A2:B65000").ClearContents
    If K Then
        .Range("A2").Resize(K, 2).Value = dArr
        .Range("A2").Resize(K, 2).Sort Sheet3.Range("A1"), xlAscending
    End If
End With
Set Dic = Nothing
End If
End Sub
 

File đính kèm

  • Chart_GPE (3).xls
    237 KB · Đọc: 7
Lần chỉnh sửa cuối:
Upvote 0
Đoạn code dưới đây đang chạy lọc ngày duy nhất có sắp xếp theo thứ tự tăng dần. Lọc dữ liệu ngày từ cột A của sheet Data, sau đó lấy kết quả cho sang cột A của sheet Chart và tính tổng giá trị của cột B sheet Data rồi cho sang cột B sheet Chart. Nó chạy rất tốt rồi. Do có 1 sheet khác em cũng dùng code này nhưng ko cần phần tính tổng. Nên Em muốn nhờ A/C giúp Em sửa code. Bỏ phần tính tổng, chỉ giữ lại code lọc ngày duy nhất có sắp xếp tăng dần. Cám ơn A/C nhiều!


Mã:
Private Sub Worksheet_Change(ByVal Target As Range)If Target.Address = "$C$1" Then
Dim sArr(), I&, J&, Dic As Object, dArr, K&, Tmp
With Sheet1
    sArr = .Range(.[A2], .[A65000].End(3)).Resize(, 2).Value
End With
ReDim dArr(1 To UBound(sArr), 1 To UBound(sArr, 2))
Set Dic = CreateObject("Scripting.Dictionary")
With Dic
    For I = 1 To UBound(sArr, 1)
        Tmp = sArr(I, 1)
        If Not .Exists(Tmp) Then
            K = K + 1
            .Add Tmp, K
            For J = 1 To UBound(sArr, 2)
                dArr(K, J) = sArr(I, J)
            Next J
        Else
            dArr(.Item(Tmp), 2) = dArr(.Item(Tmp), 2) + sArr(I, 2)
        End If
    Next I
End With
With Sheet3
        .Range("A2:B65000").ClearContents
    If K Then
        .Range("A2").Resize(K, 2).Value = dArr
        .Range("A2").Resize(K, 2).Sort Sheet3.Range("A1"), xlAscending
    End If
End With
Set Dic = Nothing
End If
End Sub
Hên xui nha: Bạn thay vì cộng lại sẽ là gộp lại ngăn bởi dấu ; hoặc , sau đó split ra theo dấu ngăn (, hoặc ;) rồi sort theo hàng
 
Upvote 0
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$C$1" Then
Dim sArr(), I&, Dic As Object, dArr, K&, Tmp
With Sheet1
    sArr = .Range(.[A2], .[A65000].End(3)).Resize(, 2).Value
End With
ReDim dArr(1 To UBound(sArr), 1 To 1)
Set Dic = CreateObject("Scripting.Dictionary")
With Dic
    For I = 1 To UBound(sArr, 1)
        Tmp = sArr(I, 1)
        If Not .Exists(Tmp) Then
            K = K + 1
            .Add Tmp, K
                dArr(K, 1) = sArr(I, 1)
        End If
    Next I
End With
With Sheet3
        .Range("A2:A65000").ClearContents
    If K Then
        .Range("A2").Resize(K).Value = dArr
        .Range("A2").Resize(K).Sort Sheet3.Range("A1"), xlAscending
    End If
End With
Set Dic = Nothing
End If
End Sub

Em cám ơn Anh! Ok rồi Anh ơi /*+
 
Upvote 0
hỏi về hàm match tương đối,
xin chào mọi người, tôi có một vấn đề mò hoài mà nó vẫn ko ra kết quả+-+-+-++-+-+-++-+-+-+, nhờ anh chị giúp đỡ

có một cột ngày được sắp xếp theo thứ tự tăng dần, tuy nhiên các ngày thì có bị lặp lại
bị giờ đi tìm vị trí ngày ở cell C5 trừ đi 1
nếu dùng hàm match trên sheet thì kết quả tốt E5
nhưng hàm match trong code thì bị lổi
nhưng khi lấy c6=c5-1 thì code lại cho ra kết quả đúng
mọi người giúp với, làm sao khắc phục nó
cám ơn
 

File đính kèm

  • hoi ham match.xlsm
    55.1 KB · Đọc: 11
Upvote 0
hỏi về hàm match tương đối,
xin chào mọi người, tôi có một vấn đề mò hoài mà nó vẫn ko ra kết quả+-+-+-++-+-+-++-+-+-+, nhờ anh chị giúp đỡ

có một cột ngày được sắp xếp theo thứ tự tăng dần, tuy nhiên các ngày thì có bị lặp lại
bị giờ đi tìm vị trí ngày ở cell C5 trừ đi 1
nếu dùng hàm match trên sheet thì kết quả tốt E5
nhưng hàm match trong code thì bị lổi
nhưng khi lấy c6=c5-1 thì code lại cho ra kết quả đúng
mọi người giúp với, làm sao khắc phục nó
cám ơn

cái này là ai hỏi đây Let' Gâu Gâu ?
 
Upvote 0
cái này là ai hỏi đây Let' Gâu Gâu ?

thì gâu gâu hỏi chứ ai.........hihihihi
tôi đang làm giúp một bạn thì bị vấn đề này
tôi ra ngoài tạo lại một file mới thì thấy nó chạy được, riêng số liệu của file này thì cứ bị như vậy
kiểm tra rất kỹ, không thấy nó sai gì về định dạng ngày...........hihih.......hết cách.........lên đây cầu cứu các thầy
 
Upvote 0
thì gâu gâu hỏi chứ ai.........hihihihi
tôi đang làm giúp một bạn thì bị vấn đề này
tôi ra ngoài tạo lại một file mới thì thấy nó chạy được, riêng số liệu của file này thì cứ bị như vậy
kiểm tra rất kỹ, không thấy nó sai gì về định dạng ngày...........hihih.......hết cách.........lên đây cầu cứu các thầy
Hihi ở đâu vậy Gâu Gâu. Cho mình đường link để nếu giải xong rùi mình học tập. Hí hí
 
Upvote 0
thì gâu gâu hỏi chứ ai.........hihihihi
tôi đang làm giúp một bạn thì bị vấn đề này
tôi ra ngoài tạo lại một file mới thì thấy nó chạy được, riêng số liệu của file này thì cứ bị như vậy
kiểm tra rất kỹ, không thấy nó sai gì về định dạng ngày...........hihih.......hết cách.........lên đây cầu cứu các thầy

kiếm các thầy thì sao tôi dám trả lời ?
Public Sub hello()
MsgBox TypeName(Application.Match([C6].Value, [a1:a26], 0))
MsgBox TypeName(Application.Match([C6].Value2, [a1:a26], 0))
MsgBox TypeName(Application.Match([C6], [a1:a26], 0))
End Sub
 
Upvote 0
cái này là ai hỏi đây Let' Gâu Gâu ?

lý do làm cái việc đó là như vậy, dữ liệu rất lớn, có tới khoảng 5,6 chục ngàn dòng (một năm), vì vậy khi người ta muốn xử lý từ ngày ....đến ngày
tôi muốn nhảy tới dòng đó để nạp từ dòng đó đến cuối vào mảng
như vậy sẻ tiết kiệm bớt vòng lặp
DoveandRose, có nhiều kinh nghiệm trong việc xử lú số liệu lớn, góp ý mình với

kiếm các thầy thì sao tôi dám trả lời ?
Public Sub hello()
MsgBox TypeName(Application.Match([C6].Value, [a1:a26], 0))
MsgBox TypeName(Application.Match([C6].Value2, [a1:a26], 0))
MsgBox TypeName(Application.Match([C6], [a1:a26], 0))
End Sub

thì DoveAndRose đạt được đẳng cấp đó rồi còn gì nữa, thấy có quá chừng cô ngưỡng mộ
trong đó có em..........nữa
 
Lần chỉnh sửa cuối:
Upvote 0
lý do làm cái việc đó là như vậy, dữ liệu rất lớn, có tới khoảng 5,6 chục ngàn dòng (một năm), vì vậy khi người ta muốn xử lý từ ngày ....đến ngày
tôi muốn nhảy tới dòng đó để nạp từ dòng đó đến cuối vào mảng
như vậy sẻ tiết kiệm bớt vòng lặp
DoveandRose, có nhiều kinh nghiệm trong việc xử lú số liệu lớn, góp ý mình với



thì DoveAndRose đạt được đẳng cấp đó rồi còn gì nữa, thấy có quá chừng cô ngưỡng mộ
trong đó có em..........nữa

xem có 1 cột thật khó trả lời nên dùng cách nào , thường thì trên 20 000 dòng thì em nghỉ chơi Match rồi chứ đừng nói nhiều hơn
dùng mảng có thể là giải pháp tốt khi mà ngày đã xếp theo thứ tự , Nhưng cần có tí lắc léo
 
Upvote 0
Web KT

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

Back
Top Bottom