Xin code lấy tất cả các giá trị cùng thỏa mãn điều kiện (1 người xem)

  • Thread starter Thread starter LYSM
  • Ngày gửi Ngày gửi
Liên hệ QC

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

LYSM

Thành viên thường trực
Tham gia
16/3/11
Bài viết
290
Được thích
26
Em chào cả nhà, em nhờ các anh chị giúp đỡ em code lấy các dữ liệu cùng thỏa mãn 1 điều kiện cho trước cụ thể như trong file đính kèm. Em cũng đã dùng hàm để lập công thức nhưng do lượng dữ liệu quá lớn nên file ỳ ạch. Kính mong các anh chị giúp đỡ. Em cảm ơn!
 

File đính kèm

Em chào cả nhà, em nhờ các anh chị giúp đỡ em code lấy các dữ liệu cùng thỏa mãn 1 điều kiện cho trước cụ thể như trong file đính kèm. Em cũng đã dùng hàm để lập công thức nhưng do lượng dữ liệu quá lớn nên file ỳ ạch. Kính mong các anh chị giúp đỡ. Em cảm ơn!
Viết code "chóng mặt" quá.
Chỉ được 1 đoạn, còn 1 đoạn lấy công thức Excel chứ "oải" rồi, không nghĩ ra cách khác.
PHP:
Public Sub ChacChet()
Application.ScreenUpdating = False
Dim Dic As Object, Arr(), ArrTem(), sArr(), dArr1(), dArr2(), I As Long, J As Long, K As Long
Dim Tem As String, Cll As Range, Gpe As Variant
Set Dic = CreateObject("Scripting.Dictionary")
Arr = Range([B7], [B7].End(xlDown)).Value
ReDim ArrTem(1 To UBound(Arr, 1), 1 To 1)
ReDim dArr1(1 To UBound(Arr, 1), 1 To 15)
ReDim dArr2(1 To UBound(Arr, 1), 1 To 3)
For I = 1 To UBound(Arr, 1)
    If Not Dic.Exists(Arr(I, 1)) Then
        K = K + 1
        Dic.Add Arr(I, 1), K
        ArrTem(K, 1) = 0
    End If
Next I
Arr = Range([Y6], [Y65000].End(xlUp)).Resize(, 14).Value
For I = 1 To UBound(Arr, 1)
    Tem = Left(Arr(I, 1), 5)
    If Dic.Exists(Tem) Then
        Gpe = Dic.Item(Tem)
        ArrTem(Gpe, 1) = ArrTem(Gpe, 1) + 1
            dArr1(Gpe, ArrTem(Gpe, 1)) = Arr(I, 5)
        ArrTem(Gpe, 1) = ArrTem(Gpe, 1) + 1
            dArr1(Gpe, ArrTem(Gpe, 1)) = Arr(I, 3)
        ArrTem(Gpe, 1) = ArrTem(Gpe, 1) + 1
            dArr1(Gpe, ArrTem(Gpe, 1)) = Arr(I, 14)
    End If
Next I
If K Then
    [I7].Resize(K, 15).Value = dArr1
    For Each Cll In Range([B7], [B7].End(xlDown)) '-----------Doan nay oai qua
        For I = 1 To 3
            Cll.Offset(, I + 1).FormulaR1C1 = "=Average(RC[5],RC[8],RC[11],RC[14],RC[17])"
        Next I
    Next    '------------------------------
    [D7:F7].Resize(K).Value = [D7:F7].Resize(K).Value
End If
Set Dic = Nothing
Application.ScreenUpdating = True
End Sub
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Em chào cả nhà, em nhờ các anh chị giúp đỡ em code lấy các dữ liệu cùng thỏa mãn 1 điều kiện cho trước cụ thể như trong file đính kèm. Em cũng đã dùng hàm để lập công thức nhưng do lượng dữ liệu quá lớn nên file ỳ ạch. Kính mong các anh chị giúp đỡ. Em cảm ơn!
Tôi thấy vùng kết quả của bạn chỉ đủ chỗ cho 5 kết quả thôi. Nếu 1 trạm có 6 kết quả thì để vào đâu vậy bạn?
 
Upvote 0
Tôi thấy vùng kết quả của bạn chỉ đủ chỗ cho 5 kết quả thôi. Nếu 1 trạm có 6 kết quả thì để vào đâu vậy bạn?

Vâng ạ, cũng có những trường hợp có 6 kết quả nhưng rất ít. Em chỉ cần biết code rồi modify cũng được, mà hình như bác cùng ngành hay sao mà nắm rõ thế :D
 
Upvote 0
Viết code "chóng mặt" quá.
Chỉ được 1 đoạn, còn 1 đoạn lấy công thức Excel chứ "oải" rồi, không nghĩ ra cách khác.
PHP:
Public Sub ChacChet()
Application.ScreenUpdating = False
Dim Dic As Object, Arr(), ArrTem(), sArr(), dArr1(), dArr2(), I As Long, J As Long, K As Long
Dim Tem As String, Cll As Range, Gpe As Variant
Set Dic = CreateObject("Scripting.Dictionary")
Arr = Range([B7], [B7].End(xlDown)).Value
ReDim ArrTem(1 To UBound(Arr, 1), 1 To 1)
ReDim dArr1(1 To UBound(Arr, 1), 1 To 15)
ReDim dArr2(1 To UBound(Arr, 1), 1 To 3)
For I = 1 To UBound(Arr, 1)
    If Not Dic.Exists(Arr(I, 1)) Then
        K = K + 1
        Dic.Add Arr(I, 1), K
        ArrTem(K, 1) = 0
    End If
Next I
Arr = Range([Y6], [Y65000].End(xlUp)).Resize(, 14).Value
For I = 1 To UBound(Arr, 1)
    Tem = Left(Arr(I, 1), 5)
    If Dic.Exists(Tem) Then
        Gpe = Dic.Item(Tem)
        ArrTem(Gpe, 1) = ArrTem(Gpe, 1) + 1
            dArr1(Gpe, ArrTem(Gpe, 1)) = Arr(I, 5)
        ArrTem(Gpe, 1) = ArrTem(Gpe, 1) + 1
            dArr1(Gpe, ArrTem(Gpe, 1)) = Arr(I, 3)
        ArrTem(Gpe, 1) = ArrTem(Gpe, 1) + 1
            dArr1(Gpe, ArrTem(Gpe, 1)) = Arr(I, 14)
    End If
Next I
If K Then
    [I7].Resize(K, 15).Value = dArr1
    For Each Cll In Range([B7], [B7].End(xlDown)) '-----------Doan nay oai qua
        For I = 1 To 3
            Cll.Offset(, I + 1).FormulaR1C1 = "=Average(RC[5],RC[8],RC[11],RC[14],RC[17])"
        Next I
    Next    '------------------------------
    [D7:F7].Resize(K).Value = [D7:F7].Resize(K).Value
End If
Set Dic = Nothing
Application.ScreenUpdating = True
End Sub

Em cảm ơn thầy nhiều ạ!
 
Upvote 0
Vâng ạ, cũng có những trường hợp có 6 kết quả nhưng rất ít. Em chỉ cần biết code rồi modify cũng được, mà hình như bác cùng ngành hay sao mà nắm rõ thế :D
Cùng ngành gì đâu. Tôi nói theo dữ liệu của bạn đó chứ.

Thêm một lựa chọn cho bạn.
PHP:
Sub cal()
On Error Resume Next
Dim ArrTram, ArrDulieu, ArrKetQua, Dic, Dong As Long, i As Long, j As Long
ArrTram = Range([B1048576].End(xlUp), [B7]).Value
ReDim ArrKetQua(1 To UBound(ArrTram, 1), 1 To 15)
ArrDulieu = Range([Y1048576].End(xlUp), [AL6]).Value
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(ArrTram, 1)
  Dic.Add ArrTram(i, 1), i
Next
ReDim ArrTram(1 To UBound(ArrTram, 1), 1 To 4) As Double
For i = 1 To UBound(ArrDulieu, 1)
  If Dic.Exists(Left(ArrDulieu(i, 1), 5)) Then
    Dong = CLng(Dic.Item(Left(ArrDulieu(i, 1), 5)))
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 1) = ArrDulieu(i, 5)
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 2) = ArrDulieu(i, 3)
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 3) = ArrDulieu(i, 14)
    ArrTram(Dong, 1) = ArrTram(Dong, 1) + ArrDulieu(i, 5)
    ArrTram(Dong, 2) = ArrTram(Dong, 2) + ArrDulieu(i, 3)
    ArrTram(Dong, 3) = ArrTram(Dong, 3) + ArrDulieu(i, 14)
    ArrTram(Dong, 4) = ArrTram(Dong, 4) + 1
  End If
Next
For i = 1 To UBound(ArrTram, 1)
  For j = 1 To 3
    ArrTram(i, j) = ArrTram(i, j) / ArrTram(i, 4)
  Next
Next
[D7:F7].Resize(UBound(ArrTram, 1)).Value = ArrTram
[I7:W7].Resize(UBound(ArrKetQua, 1)).Value = ArrKetQua
End Sub
 
Upvote 0
@ Thầy Ba Tê: Thầy ơi, khi cột B của em bị cách một dòng thì các dòng dưới sẽ không tính được nữa, có cách nào khắc phục cái này không ạ?
 

File đính kèm

Upvote 0
Cùng ngành gì đâu. Tôi nói theo dữ liệu của bạn đó chứ.

Thêm một lựa chọn cho bạn.
PHP:
Sub cal()
On Error Resume Next
Dim ArrTram, ArrDulieu, ArrKetQua, Dic, Dong As Long, i As Long, j As Long
ArrTram = Range([B1048576].End(xlUp), [B7]).Value
ReDim ArrKetQua(1 To UBound(ArrTram, 1), 1 To 15)
ArrDulieu = Range([Y1048576].End(xlUp), [AL6]).Value
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(ArrTram, 1)
  Dic.Add ArrTram(i, 1), i
Next
ReDim ArrTram(1 To UBound(ArrTram, 1), 1 To 4) As Double
For i = 1 To UBound(ArrDulieu, 1)
  If Dic.Exists(Left(ArrDulieu(i, 1), 5)) Then
    Dong = CLng(Dic.Item(Left(ArrDulieu(i, 1), 5)))
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 1) = ArrDulieu(i, 5)
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 2) = ArrDulieu(i, 3)
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 3) = ArrDulieu(i, 14)
    ArrTram(Dong, 1) = ArrTram(Dong, 1) + ArrDulieu(i, 5)
    ArrTram(Dong, 2) = ArrTram(Dong, 2) + ArrDulieu(i, 3)
    ArrTram(Dong, 3) = ArrTram(Dong, 3) + ArrDulieu(i, 14)
    ArrTram(Dong, 4) = ArrTram(Dong, 4) + 1
  End If
Next
For i = 1 To UBound(ArrTram, 1)
  For j = 1 To 3
    ArrTram(i, j) = ArrTram(i, j) / ArrTram(i, 4)
  Next
Next
[D7:F7].Resize(UBound(ArrTram, 1)).Value = ArrTram
[I7:W7].Resize(UBound(ArrKetQua, 1)).Value = ArrKetQua
End Sub
Em xin chân thành cảm ơn bác nhiều!
 
Upvote 0
Cùng ngành gì đâu. Tôi nói theo dữ liệu của bạn đó chứ.

Thêm một lựa chọn cho bạn.
PHP:
Sub cal()
On Error Resume Next
Dim ArrTram, ArrDulieu, ArrKetQua, Dic, Dong As Long, i As Long, j As Long
ArrTram = Range([B1048576].End(xlUp), [B7]).Value
ReDim ArrKetQua(1 To UBound(ArrTram, 1), 1 To 15)
ArrDulieu = Range([Y1048576].End(xlUp), [AL6]).Value
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(ArrTram, 1)
  Dic.Add ArrTram(i, 1), i
Next
ReDim ArrTram(1 To UBound(ArrTram, 1), 1 To 4) As Double
For i = 1 To UBound(ArrDulieu, 1)
  If Dic.Exists(Left(ArrDulieu(i, 1), 5)) Then
    Dong = CLng(Dic.Item(Left(ArrDulieu(i, 1), 5)))
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 1) = ArrDulieu(i, 5)
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 2) = ArrDulieu(i, 3)
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 3) = ArrDulieu(i, 14)
    ArrTram(Dong, 1) = ArrTram(Dong, 1) + ArrDulieu(i, 5)
    ArrTram(Dong, 2) = ArrTram(Dong, 2) + ArrDulieu(i, 3)
    ArrTram(Dong, 3) = ArrTram(Dong, 3) + ArrDulieu(i, 14)
    ArrTram(Dong, 4) = ArrTram(Dong, 4) + 1
  End If
Next
For i = 1 To UBound(ArrTram, 1)
  For j = 1 To 3
    ArrTram(i, j) = ArrTram(i, j) / ArrTram(i, 4)
  Next
Next
[D7:F7].Resize(UBound(ArrTram, 1)).Value = ArrTram
[I7:W7].Resize(UBound(ArrKetQua, 1)).Value = ArrKetQua
End Sub
Bác ơi, code này của bác nó lấy cả các giá trị rỗng để tính trung bình. Em muốn nó tính trung bình nhưng phải loại đi những giá trị rỗng ạ. Bác xem giúp em ví dụ ở file đính kèm. Chúc bác một tuần mới vui vẻ và may mắn!
Em cảm ơn nhiều!
 

File đính kèm

Upvote 0
Bác ơi, code này của bác nó lấy cả các giá trị rỗng để tính trung bình. Em muốn nó tính trung bình nhưng phải loại đi những giá trị rỗng ạ. Bác xem giúp em ví dụ ở file đính kèm. Chúc bác một tuần mới vui vẻ và may mắn!
Em cảm ơn nhiều!
Tôi sửa lại như sau. Bạn thử xem.
PHP:
Sub cal()
On Error Resume Next
Dim ArrTram, ArrDulieu, ArrKetQua, Dic, Dong As Long, i As Long, j As Long
ArrTram = Range([B1048576].End(xlUp), [B7]).Value
ReDim ArrKetQua(1 To UBound(ArrTram, 1), 1 To 24)
ArrDulieu = Range([AH1048576].End(xlUp), [AU6]).Value
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(ArrTram, 1)
  Dic.Add ArrTram(i, 1), i
Next
ReDim ArrTram(1 To UBound(ArrTram, 1), 1 To 6) As Double
For i = 1 To UBound(ArrDulieu, 1)
  If Dic.Exists(Left(ArrDulieu(i, 1), 5)) Then
    Dong = CLng(Dic.Item(Left(ArrDulieu(i, 1), 5)))
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 1) = ArrDulieu(i, 5)
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 2) = ArrDulieu(i, 3)
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 3) = ArrDulieu(i, 14)
    ArrTram(Dong, 1) = ArrTram(Dong, 1) + ArrDulieu(i, 5)
    ArrTram(Dong, 2) = ArrTram(Dong, 2) + ArrDulieu(i, 3)
    ArrTram(Dong, 3) = ArrTram(Dong, 3) + ArrDulieu(i, 14)
    If ArrDulieu(i, 5) <> vbNullString Then ArrTram(Dong, 4) = ArrTram(Dong, 4) + 1
    If ArrDulieu(i, 3) <> vbNullString Then ArrTram(Dong, 5) = ArrTram(Dong, 5) + 1
    If ArrDulieu(i, 14) <> vbNullString Then ArrTram(Dong, 6) = ArrTram(Dong, 6) + 1
  End If
Next
For i = 1 To UBound(ArrTram, 1)
  For j = 1 To 3
    ArrTram(i, j) = ArrTram(i, j) / IIf(ArrTram(i, j + 3) = 0, 1, ArrTram(i, j + 3))
  Next
Next
[D7:F7].Resize(UBound(ArrTram, 1)).Value = ArrTram
[I7:AF7].Resize(UBound(ArrKetQua, 1)).Value = ArrKetQua
End Sub
 
Upvote 0
Tôi sửa lại như sau. Bạn thử xem.
PHP:
Sub cal()
On Error Resume Next
Dim ArrTram, ArrDulieu, ArrKetQua, Dic, Dong As Long, i As Long, j As Long
ArrTram = Range([B1048576].End(xlUp), [B7]).Value
ReDim ArrKetQua(1 To UBound(ArrTram, 1), 1 To 24)
ArrDulieu = Range([AH1048576].End(xlUp), [AU6]).Value
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(ArrTram, 1)
  Dic.Add ArrTram(i, 1), i
Next
ReDim ArrTram(1 To UBound(ArrTram, 1), 1 To 6) As Double
For i = 1 To UBound(ArrDulieu, 1)
  If Dic.Exists(Left(ArrDulieu(i, 1), 5)) Then
    Dong = CLng(Dic.Item(Left(ArrDulieu(i, 1), 5)))
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 1) = ArrDulieu(i, 5)
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 2) = ArrDulieu(i, 3)
    ArrKetQua(Dong, ArrTram(Dong, 4) * 3 + 3) = ArrDulieu(i, 14)
    ArrTram(Dong, 1) = ArrTram(Dong, 1) + ArrDulieu(i, 5)
    ArrTram(Dong, 2) = ArrTram(Dong, 2) + ArrDulieu(i, 3)
    ArrTram(Dong, 3) = ArrTram(Dong, 3) + ArrDulieu(i, 14)
    If ArrDulieu(i, 5) <> vbNullString Then ArrTram(Dong, 4) = ArrTram(Dong, 4) + 1
    If ArrDulieu(i, 3) <> vbNullString Then ArrTram(Dong, 5) = ArrTram(Dong, 5) + 1
    If ArrDulieu(i, 14) <> vbNullString Then ArrTram(Dong, 6) = ArrTram(Dong, 6) + 1
  End If
Next
For i = 1 To UBound(ArrTram, 1)
  For j = 1 To 3
    ArrTram(i, j) = ArrTram(i, j) / IIf(ArrTram(i, j + 3) = 0, 1, ArrTram(i, j + 3))
  Next
Next
[D7:F7].Resize(UBound(ArrTram, 1)).Value = ArrTram
[I7:AF7].Resize(UBound(ArrKetQua, 1)).Value = ArrKetQua
End Sub
Chưa ổn lắm bác ạ, của em có 3 trường hợp
1, cả ba ArrDulieu(i, 3), ArrDulieu(i, 5), ArrDulieu(i, 14) đều khác rỗng (có kết quả)
2, ArrDulieu(i, 3) và ArrDulieu(i, 5) cùng rỗng , ArrDulieu(i, 14) khác rỗng
3, ArrDulieu(i, 3) và ArrDulieu(i, 5) khác rỗng, ArrDulieu(i, 14) rỗng
Như code trên của bác nếu rơi vào TH 2 thì mảng kết quả sẽ thiếu ArrDulieu(i,14)
 
Lần chỉnh sửa cuối:
Upvote 0
Chưa ổn lắm bác ạ, của em có 3 trường hợp
1, cả ba ArrDulieu(i, 3), ArrDulieu(i, 5), ArrDulieu(i, 14) đều khác rỗng (có kết quả)
2, ArrDulieu(i, 3) và ArrDulieu(i, 5) cùng rỗng , ArrDulieu(i, 14) khác rỗng
3, ArrDulieu(i, 3) và ArrDulieu(i, 5) khác rỗng, ArrDulieu(i, 14) rỗng
Như code trên của bác nếu rơi vào TH 2 thì mảng kết quả sẽ thiếu ArrDulieu(i,14)
Lúc nãy sửa tôi không xem kỹ lại. Bạn thử lại code này.
PHP:
Sub cal()
On Error Resume Next
Dim ArrTram, ArrDulieu, ArrKetQua, Dic, Dong As Long, i As Long, j As Long
ArrTram = Range([B1048576].End(xlUp), [B7]).Value
ReDim ArrKetQua(1 To UBound(ArrTram, 1), 1 To 24)
ArrDulieu = Range([AH1048576].End(xlUp), [AU6]).Value
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(ArrTram, 1)
  Dic.Add ArrTram(i, 1), i
Next
ReDim ArrTram(1 To UBound(ArrTram, 1), 1 To 7) As Double
For i = 1 To UBound(ArrDulieu, 1)
  If Dic.Exists(Left(ArrDulieu(i, 1), 5)) Then
    Dong = CLng(Dic.Item(Left(ArrDulieu(i, 1), 5)))
    ArrKetQua(Dong, ArrTram(Dong, 7) * 3 + 1) = ArrDulieu(i, 5)
    ArrKetQua(Dong, ArrTram(Dong, 7) * 3 + 2) = ArrDulieu(i, 3)
    ArrKetQua(Dong, ArrTram(Dong, 7) * 3 + 3) = ArrDulieu(i, 14)
    ArrTram(Dong, 1) = ArrTram(Dong, 1) + ArrDulieu(i, 5)
    ArrTram(Dong, 2) = ArrTram(Dong, 2) + ArrDulieu(i, 3)
    ArrTram(Dong, 3) = ArrTram(Dong, 3) + ArrDulieu(i, 14)
    If ArrDulieu(i, 5) <> vbNullString Then ArrTram(Dong, 4) = ArrTram(Dong, 4) + 1
    If ArrDulieu(i, 3) <> vbNullString Then ArrTram(Dong, 5) = ArrTram(Dong, 5) + 1
    If ArrDulieu(i, 14) <> vbNullString Then ArrTram(Dong, 6) = ArrTram(Dong, 6) + 1
    ArrTram(Dong, 7) = ArrTram(Dong, 7) + 1
  End If
Next
For i = 1 To UBound(ArrTram, 1)
  For j = 1 To 3
    ArrTram(i, j) = ArrTram(i, j) / IIf(ArrTram(i, j + 3) = 0, 1, ArrTram(i, j + 3))
  Next
Next
[D7:F7].Resize(UBound(ArrTram, 1)).Value = ArrTram
[I7:AF7].Resize(UBound(ArrKetQua, 1)).Value = ArrKetQua
End Sub
 
Upvote 0

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

Back
Top Bottom