Code VBA tra cứu kết quả trả về mảng dữ liệu (1 người xem)

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

Tôi tuân thủ nội quy khi đăng bài

tiendu02

Thành viên mới
Tham gia
23/2/20
Bài viết
7
Được thích
1
Em chào các anh/chị trong diễn đàn ạ.
Các anh/chị trong diễn đàn có ai biết code VBA tra cứu kết quả trả về mảng dữ liệu không ạ? Chỉ giúp em với.
Em có file excel gồm 2 Sheet: Sheet "Data" và Sheet "Bang do". Bài toán yêu cầu là khi em nhập bất kỳ một mã nào đó ở một hàng bất kỳ của cột Mã trong Sheet "Bang do" thì các thông số của mã đó sẽ được lấy ra từ Sheet "Data" và giữ nguyên định dạng ạ. (File excel phía dưới).
Em cảm ơn anh/chị trong diễn đàn ạ.
 

File đính kèm

Lần chỉnh sửa cuối:
Bạn xem file & trên máy của mình đã đúng luôn định dạng rồi nha
 

File đính kèm

Upvote 0
Em chào các anh/chị trong diễn đàn ạ.
Các anh/chị trong diễn đàn có ai biết code VBA tra cứu kết quả trả về mảng dữ liệu không ạ? Chỉ giúp em với.
Em có file excel gồm 2 Sheet: Sheet "Data" và Sheet "Bang do". Bài toán yêu cầu là khi em nhập bất kỳ một mã nào đó ở một hàng bất kỳ của cột Mã trong Sheet "Bang do" thì các thông số của mã đó sẽ được lấy ra từ Sheet "Data" và giữ nguyên định dạng ạ. (File excel phía dưới).
Em cảm ơn anh/chị trong diễn đàn ạ.
Góp vui.
bạn thử gõ số (1,2,3,....) vào Cột A bảng dò và Gõ Enter xem điều gì đã diễn ra.
Xem file
 

File đính kèm

Upvote 0
Em cảm ơn anh/chị nhiều ạ
Bài đã được tự động gộp:

Góp vui.
bạn thử gõ số (1,2,3,....) vào Cột A bảng dò và Gõ Enter xem điều gì đã diễn ra.
Xem file
Anh có thể thêm câu lệnh giúp em là khi em xóa mã trong cột Mã của Sheet "Bang do" thì các thông số của mã đó cũng sẽ tự động xóa đi với ạ.
 
Lần chỉnh sửa cuối:
Upvote 0
Em cảm ơn anh/chị nhiều ạ
Bài đã được tự động gộp:


Anh có thể thêm câu lệnh giúp em là khi em xóa mã trong cột Mã của Sheet "Bang do" thì các thông số của mã đó cũng sẽ tự động xóa đi với ạ.
Tức là Khi cột A/ bảng dò đã có 1 mã nào đó ví dụ là số 3. và các cột B-G đã có số liệu. Giờ xóa số 3 ở cột A đi thì lập tức dữ liệu của mã sô 3 ấy (từ cột B-G của sheet bảng dò) cũng bị xóa
 
Upvote 0
Thay code Trong Sheet Bang do bằng code này:
Dùng tạm trong khi chờ giải pháp tốt hơn.

Mã:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A3: A100000")) Is Nothing Then
    If Not IsEmpty(Target) Then
        Dim Rng As Range, R&, R2&
        Dim d&, Lr&
        Dim Sh As Worksheet
        Dim Ma
            Ma = Target
            Set Sh = Sheets("Data")
            Lr = Sh.Range("A1000000").End(xlUp).Row
            Set Rng = Sh.Range("A1:A" & Lr)
        If Not Rng.Find(Ma) Is Nothing Then
            R = Rng.Find(Ma).Row: d = Target.Row
            R2 = Sh.Range("A" & R).End(xlDown).Row - 1
            Sh.Range("B" & R, "G" & R2).Copy Range("B" & d)
        End If
    Else
    Dim Cell
   
 Dim Cell
        R = Target.Row
        R2 = Range("A" & R).End(xlDown).Row - 1
        If R2 >= 1048500 Then R2 = Range("B1048575").End(xlUp).Row
            Range("B" & R, "G" & R2).ClearContents
    End If
End If
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Mã:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A3: A100000")) Is Nothing Then
    If Not IsEmpty(Target) Then
        Dim Rng As Range, R&, R2&
        Dim d&, Lr&
        Dim Sh As Worksheet
        Dim Ma
            Ma = Target
            Set Sh = Sheets("Data")
            Lr = Sh.Range("A1000000").End(xlUp).Row
            Set Rng = Sh.Range("A1:A" & Lr)
        If Not Rng.Find(Ma) Is Nothing Then
            R = Rng.Find(Ma).Row: d = Target.Row
            R2 = Sh.Range("A" & R).End(xlDown).Row - 1
            Sh.Range("B" & R, "G" & R2).Copy Range("B" & d)
        End If
    Else
    Dim Cell
  
 Dim Cell
        R = Target.Row
        R2 = Range("A" & R).End(xlDown).Row - 1
        If R2 >= 1048500 Then R2 = Range("B1048575").End(xlUp).Row
            Range("B" & R, "G" & R2).ClearContents
    End If
End If
End Sub
Dựa theo macro sự kiện này ta có thể chuyển thể sang UDF
Tuy nhiên dữ liệu trả về không kèm theo định dạng như tác giả bài đăng mong muốn;
Còn xài E365 thì có thể có hàm cho ra mảng kết quả luôn!
 
Upvote 0
Dựa theo macro sự kiện này ta có thể chuyển thể sang UDF
Tuy nhiên dữ liệu trả về không kèm theo định dạng như tác giả bài đăng mong muốn;
Còn xài E365 thì có thể có hàm cho ra mảng kết quả luôn!
Dạ em cảm ơn anh ạ. Em có Copy Code và đã thử ạ, nhưng có một vấn đề phát sinh là khi em đổi mã của cột Mã trong Sheet "Bang do". Ví dụ đổi từ mã 2 sang mã 1 do thông số của mã 2 nhiều hơn thông số của mã 1 thì khi mình chuyển đổi vậy, nó sẽ bị sót lại các thông số thừa của mã 2 ạ. Anh khắc phục giúp em với ạ
 
Upvote 0
Trong macro sự kiện có ngay lúc mới vô là dòng lệnh xóa dữ liệu cũ; & nó đang là thế này
PHP:
Target.Offset(, 1).Resize(54, 6).Value = Space(0)
Dịch sang tiếng Việt sẽ là Xóa 54 dòng & 6 cột (dữ liệu) kể từ ô bên phải liền kề với ô vừa nhập;
Con số 54 là mình án chừng; Nếu nó còn nhỏ thì bạn tăng lên
[Bảng dữ liệu của bạn có 1126 dòng + 1;
(/ới 112 mã công việc thì 1126/60 mình cứ đinh ninh là OK; xin lỗi bạn về điều này nha!]
 
Upvote 0
Dạ em cảm ơn anh ạ. Em có Copy Code và đã thử ạ, nhưng có một vấn đề phát sinh là khi em đổi mã của cột Mã trong Sheet "Bang do". Ví dụ đổi từ mã 2 sang mã 1 do thông số của mã 2 nhiều hơn thông số của mã 1 thì khi mình chuyển đổi vậy, nó sẽ bị sót lại các thông số thừa của mã 2 ạ. Anh khắc phục giúp em với ạ
Thử code này xem sao (tôi chưa thử kỹ)- chắc vẫn còn sai sót.

Mã:
Option Explicit


Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Not Intersect(Target, Range("A3: A100000")) Is Nothing Then
    If Not IsEmpty(Target) Then
        Dim Rng As Range, R&, R2&, X&
        Dim d&, Lr&, d1&
        Dim Sh As Worksheet, Arr()
        Dim Ma, A As Boolean
            Ma = Target
            Set Sh = Sheets("Data")
            Lr = Sh.Range("A1000000").End(xlUp).Row
            Set Rng = Sh.Range("A1:A" & Lr)
On Error Resume Next
A = True
        If Not Rng.Find(Ma) Is Nothing Then
            d = Target.Row
            d1 = Range("A" & d).End(xlDown).Row
            If d1 >= 1048500 Then d1 = Range("B1048576").End(xlUp).Row

            If d1 > d Then A = False: Range("B" & d, "G" & d1 - 1).ClearContents
            R = Rng.Find(Ma).Row:
            R2 = Sh.Range("A" & R).End(xlDown).Row - 1
If A = True Then GoTo Run
            X = (R2 - R) - (d1 - d)
            If X > 0 Then
                Rows(d1 & ":" & d1 + X).Insert Shift:=xlDown  ', CopyOrigin:=xlFormatFromLeftOrAbove
            ElseIf X < 0 Then
                Rows(d1 + (X + 1) & ":" & d1).Delete Shift:=xlUp
            End If
Run:
            Sh.Range("A" & R, "G" & R2).Copy Range("A" & d)
        End If
    Else
        Dim Cell

        d = Target.Row
        d1 = Range("A" & d).End(xlDown).Row
        If d1 >= 1048500 Then d1 = Range("B1048575").End(xlUp).Row
 '           Range("B" & d, "G" & d1 - 1).ClearContents
            Rows(d & ":" & d1 - 1).Delete Shift:=xlUp
    End If
End If
Application.EnableEvents = True
End Sub
 
Upvote 0
Em có copy code và chạy thử ạ, code có bị sai sót chút ạ. Em có đánh mã 3 thì thông số của mã hiển thị thừa thông tin ạ.
 
Upvote 0
Em có copy code và chạy thử ạ, code có bị sai sót chút ạ. Em có đánh mã 3 thì thông số của mã hiển thị thừa thông tin ạ.
Nếu tôi không lầm thì chạy trên máy tôi thì
Nếu mã mới có số dòng nhiều hơn só dòng của mã cũ thì việc chèn thêm 1 số dòng để vừa đủ với số dòng của mã cũ.
Nếu Mã mới có số dòng ít hơn số dòng mã mới thì có lúc xóa bớt dòng (trước khí xóa sữ liệu) để vừa đủ với số dòng mã mới, có lúc thì lại xóa quá 1 dòng,
Do khuya quá nên không muốn xem để sửa lại được. bạn xem code chỗ If X>0 then (....Insert Shift:=xlDown
....) .... và If X< 0 then ...Delete Shift:=xlUp
....để điều chỉnh chỗ .... ấy cho phù hợp nhé.
Tôi tin là bài này vẫn có cách khác hơn để giải quyết. Tiếc rằng tôi không đủ trình để làm được.
 
Upvote 0
Nếu tôi không lầm thì chạy trên máy tôi thì
Nếu mã mới có số dòng nhiều hơn só dòng của mã cũ thì việc chèn thêm 1 số dòng để vừa đủ với số dòng của mã cũ.
Nếu Mã mới có số dòng ít hơn số dòng mã mới thì có lúc xóa bớt dòng (trước khí xóa sữ liệu) để vừa đủ với số dòng mã mới, có lúc thì lại xóa quá 1 dòng,
Do khuya quá nên không muốn xem để sửa lại được. bạn xem code chỗ If X>0 then (....Insert Shift:=xlDown
....) .... và If X< 0 then ...Delete Shift:=xlUp
....để điều chỉnh chỗ .... ấy cho phù hợp nhé.
Tôi tin là bài này vẫn có cách khác hơn để giải quyết. Tiếc rằng tôi không đủ trình để làm được.
Em cảm ơn anh nhiều ạ!
 
Upvote 0
Mình có ý tưởng khác là coi cột A là cột list mã và khi bạn nhập mã ở ô bất kỳ từ A3:A100000 thì tự động xếp mã theo thứ tự bạn nhập tương ứng với số dòng ở sheet DATA như vậy khi bạn thay đổi mã cho 1 mã bất kì thì dữ liệu B:G cũng thay đổi theo.
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Sh As Worksheet
    Dim lastInput As Long, lastUsed As Long
    Dim arrInput As Variant, tmp As Variant
    Dim r As Long, curRow As Long
    Dim v As String
    Dim f As Range
    Dim startData As Long, endData As Long, numRows As Long
    
    On Error GoTo ErrHandler
    
    If Intersect(Target, Me.Range("A3:A100000")) Is Nothing Then Exit Sub
    If Target.Count > 1 Then Exit Sub
    
    Application.EnableEvents = False
    Set Sh = ThisWorkbook.Worksheets("Data")
    
    lastInput = Me.Cells(Me.Rows.Count, "A").End(xlUp).Row
    If lastInput < 3 Then
        lastUsed = Application.Max(3, Me.Cells(Me.Rows.Count, "B").End(xlUp).Row)
        Me.Range("A3:G" & lastUsed).ClearContents
        GoTo CleanExit
    End If
    
    arrInput = Me.Range("A3:A" & lastInput).Value
    If Not IsArray(arrInput) Then
        ReDim tmp(1 To 1, 1 To 1)
        tmp(1, 1) = arrInput
        arrInput = tmp
    End If
    
    lastUsed = Application.Max(lastInput, Me.Cells(Me.Rows.Count, "B").End(xlUp).Row)
    If lastUsed >= 3 Then Me.Range("A3:G" & lastUsed).ClearContents
    
    curRow = 3
    For r = 1 To UBound(arrInput, 1)
        v = Trim(arrInput(r, 1))
        If v <> "" Then
          
            Set f = Sh.Columns(1).Find(What:=v, LookAt:=xlWhole, SearchOrder:=xlByRows)
            If Not f Is Nothing Then
                startData = f.Row
              
                endData = Sh.Cells(startData, 1).End(xlDown).Row - 1
                If endData < startData Then
                    endData = Sh.Cells(Sh.Rows.Count, 1).End(xlUp).Row
                End If
                numRows = endData - startData + 1
                
                Me.Cells(curRow, "A").Value = v
              
                Sh.Range("B" & startData & ":G" & endData).Copy _
                    Destination:=Me.Cells(curRow, "B")
                
                curRow = curRow + numRows + 1
            Else
              
                Me.Cells(curRow, "A").Value = v
                curRow = curRow + 2
            End If
        End If
    Next r
    
CleanExit:
    Application.EnableEvents = True
    Exit Sub   
ErrHandler:
    Application.EnableEvents = True
End Sub
 
Upvote 0
Mình có ý tưởng khác là coi cột A là cột list mã và khi bạn nhập mã ở ô bất kỳ từ A3:A100000 thì tự động xếp mã theo thứ tự bạn nhập tương ứng với số dòng ở sheet DATA như vậy khi bạn thay đổi mã cho 1 mã bất kì thì dữ liệu B:G cũng thay đổi theo.
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Sh As Worksheet
    Dim lastInput As Long, lastUsed As Long
    Dim arrInput As Variant, tmp As Variant
    Dim r As Long, curRow As Long
    Dim v As String
    Dim f As Range
    Dim startData As Long, endData As Long, numRows As Long
   
    On Error GoTo ErrHandler
   
    If Intersect(Target, Me.Range("A3:A100000")) Is Nothing Then Exit Sub
    If Target.Count > 1 Then Exit Sub
   
    Application.EnableEvents = False
    Set Sh = ThisWorkbook.Worksheets("Data")
   
    lastInput = Me.Cells(Me.Rows.Count, "A").End(xlUp).Row
    If lastInput < 3 Then
        lastUsed = Application.Max(3, Me.Cells(Me.Rows.Count, "B").End(xlUp).Row)
        Me.Range("A3:G" & lastUsed).ClearContents
        GoTo CleanExit
    End If
   
    arrInput = Me.Range("A3:A" & lastInput).Value
    If Not IsArray(arrInput) Then
        ReDim tmp(1 To 1, 1 To 1)
        tmp(1, 1) = arrInput
        arrInput = tmp
    End If
   
    lastUsed = Application.Max(lastInput, Me.Cells(Me.Rows.Count, "B").End(xlUp).Row)
    If lastUsed >= 3 Then Me.Range("A3:G" & lastUsed).ClearContents
   
    curRow = 3
    For r = 1 To UBound(arrInput, 1)
        v = Trim(arrInput(r, 1))
        If v <> "" Then
         
            Set f = Sh.Columns(1).Find(What:=v, LookAt:=xlWhole, SearchOrder:=xlByRows)
            If Not f Is Nothing Then
                startData = f.Row
             
                endData = Sh.Cells(startData, 1).End(xlDown).Row - 1
                If endData < startData Then
                    endData = Sh.Cells(Sh.Rows.Count, 1).End(xlUp).Row
                End If
                numRows = endData - startData + 1
               
                Me.Cells(curRow, "A").Value = v
             
                Sh.Range("B" & startData & ":G" & endData).Copy _
                    Destination:=Me.Cells(curRow, "B")
               
                curRow = curRow + numRows + 1
            Else
             
                Me.Cells(curRow, "A").Value = v
                curRow = curRow + 2
            End If
        End If
    Next r
   
CleanExit:
    Application.EnableEvents = True
    Exit Sub  
ErrHandler:
    Application.EnableEvents = True
End Sub
Dạ, anh có thể chỉnh lại code giúp em là khi ta điền mã trong cột Mã của Sheet "Bangdo" ở bất kỳ hàng nào đó thì các thông số của mã sẽ điền ở hàng mà ta điền mã (không tự động nhảy hàng), được không ạ? Mục đích là để em so sánh thông số mã của mình lập với thông số mã của người khác lập ạ.Anh minh hoa.png
 
Upvote 0
Code là tự động xếp mã theo số hàng ở sheet DATA. Như vậy nếu bạn điền A3=1 , A4 =2 mà muốn giữ nguyên không xếp thì mã 2 sẽ đè lên mã 1 như vậy không hợp lý. còn nếu bạn muốn code chạy để mã 2 xếp cách mã 1 là 3 dòng như hình thì bạn sửa lại code phần curRow:
Mã:
If Not f Is Nothing Then
                startData = f.Row
              
                endData = Sh.Cells(startData, 1).End(xlDown).Row - 1
                If endData < startData Then
                    endData = Sh.Cells(Sh.Rows.Count, 1).End(xlUp).Row
                End If
                numRows = endData - startData + 1
                
                Me.Cells(curRow, "A").Value = v
              
                Sh.Range("B" & startData & ":G" & endData).Copy _
                    Destination:=Me.Cells(curRow, "B")
                
                curRow = curRow + numRows + 3
            Else
              
                Me.Cells(curRow, "A").Value = v
                curRow = curRow + 4
            End If
1758101971642.png
 
Upvote 0
Dạ, anh có thể chỉnh lại code giúp em là khi ta điền mã trong cột Mã của Sheet "Bangdo" ở bất kỳ hàng nào đó thì các thông số của mã sẽ điền ở hàng mà ta điền mã (không tự động nhảy hàng), được không ạ? Mục đích là để em so sánh thông số mã của mình lập với thông số mã của người khác lập ạ.View attachment 309693
Tôi biết là bạn đã có code của bạn khác rồi, nhưng mạn phép "cố đám ăn XÔI" thêm 1 bài nữa, hy vọng giúp được ai đó khi cần tham khảo.
Thay code trong sheet Bang do bằng code này. (đã kiểm tra chạy ổn)
Nếu điều này làm phiền ai đó, xin được bỏ qua và cảm thông.
Mã:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Not Intersect(Target, Range("A3: A100000")) Is Nothing Then
    If Not IsEmpty(Target) Then
        Dim Rng As Range, R&, R2&, X&
        Dim d&, Lr&, d1&
        Dim Sh As Worksheet, Arr()
        Dim Ma, A As Boolean
            Ma = Target
            Set Sh = Sheets("Data")
            Lr = Sh.Range("A1000000").End(xlUp).Row
            Set Rng = Sh.Range("A1:A" & Lr)
On Error Resume Next
        If Not Rng.Find(Ma) Is Nothing Then
            d = Target.Row
            d1 = Range("A" & d).End(xlDown).Row - 1
            R = Rng.Find(Ma).Row:
            R2 = Sh.Range("A" & R).End(xlDown).Row - 1
            If d1 >= 1048500 Then
                Lr = Range("B1000000").End(xlUp).Row
                Range("B" & d, "G" & Lr + 1).ClearContents
                GoTo Run
            Else
                Range("B" & d, "G" & d1).ClearContents
                GoTo Run1
            End If
Run1:
            X = (R2 - R) - (d1 - d)
            If X > 0 Then
                Rows(d1 & ":" & d1 + X - 1).Insert Shift:=xlDown ', CopyOrigin:=xlFormatFromLeftOrAbove
            ElseIf X < 0 Then
                Rows(d1 & ":" & d1 + 1 + X).Delete Shift:=xlUp
            End If
Run:
            Sh.Range("A" & R, "G" & R2).Copy Range("A" & d)
        End If
    Else
        Dim Cell
        d = Target.Row
        d1 = Range("A" & d).End(xlDown).Row
        If d1 >= 1048500 Then d1 = Range("B1048575").End(xlUp).Row
 '           Range("B" & d, "G" & d1 - 1).ClearContents
            Rows(d & ":" & d1 - 1).Delete Shift:=xlUp
    End If
End If
Application.EnableEvents = True
End Sub
 
Upvote 0

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

Back
Top Bottom