Chuyên mục xử lý, gỡ rối code VBA

Liên hệ QC
Status
Không mở trả lời sau này.

ndu96081631

Huyền thoại GPE
Thành viên BQT
Super Moderator
Tham gia
5/6/08
Bài viết
30,703
Được thích
53,924
Chỉnh lại dArr cho hợp lý hơn
sArr = .Range("B6", .Range("B65000").End(xlUp)).Resize(, 34).Value
ReDim dArr(1 To UBound(sArr, 1) - 1, 1 To 34)

Dic.Item(CStr(sArr(I, 1))) = I - 1

Sheets("Tong hop cong").Range("B7").Resize(UBound(dArr), 34) = dArr
Mã:
Private Sub Tong_cong1()
Dim Dic As Object, Col As Object, ws As Worksheet, Tem As String, Rws As Long
Dim R As Long, I As Long, J As Long, K As Long, C As Long
Dim sArr As Variant
Set Dic = CreateObject("Scripting.Dictionary")

Set Col = CreateObject("Scripting.Dictionary")
With Application
    .CalculateBeforeSave = False
    .Calculation = xlCalculationManual
    .ScreenUpdating = False
    .EnableEvents = False
    .EnableCancelKey = xlErrorHandler
End With
With Sheets("Tong hop cong")
    If CStr(.Range("C7")) <> "" Then
        .Range("C8:BP7000").ClearContents
    End If
    sArr = .Range("B6", .Range("B65000").End(xlUp)).Resize(, 34).Value
    ReDim dArr(1 To UBound(sArr, 1) - 1, 1 To 34)
    For J = 4 To 34
        If sArr(1, J) <> Empty Then
            If IsDate(sArr(1, J)) Then Col.Item(Day(sArr(1, J))) = J
        End If
    Next J
    For I = 2 To UBound(sArr, 1)
        If Len(sArr(I, 1)) > 0 Then
            Dic.Item(CStr(sArr(I, 1))) = I - 1
        End If
    Next I
End With
For Each ws In Worksheets
    If IsNumeric(ws.Name) Then
        C = Col.Item(Val(ws.Name))
        sArr = ws.Range("B2", ws.Range("B65000").End(xlUp)).Resize(, 17).Value
        For I = 1 To UBound(sArr, 1)
            Tem = sArr(I, 1)
            If Dic.exists(CStr(Tem)) Then
                K = Dic.Item(Tem)
                dArr(K, 1) = Tem
                dArr(K, 2) = sArr(I, 2)
                dArr(K, 3) = sArr(I, 3)
                dArr(K, C) = sArr(I, 17)
            End If
        Next I
    End If
Next ws
Sheets("Tong hop cong").Range("B7").Resize(UBound(dArr), 34) = dArr
Set Dic = Nothing
Set Col = Nothing
With Application
    .CalculateBeforeSave = True
    .Calculation = xlCalculationAutomatic
    .ScreenUpdating = True
    .EnableEvents = True
    .CalculateBeforeSave = True
    .EnableCancelKey = xlInterrupt
End With
End Sub

- Cái chỗ ReDim dArr(1 To UBound(sArr, 1) - 1, 1 To 34)
Chắc là để loại bỏ N/A mà không phải trừ 1 phần tử khi gán mảng dArr phải không anh?

- Vậy thì đoạn này: Dic.Item(CStr(sArr(I, 1))) = I - 1 tại sao phải trừ 1? Code của em không trừ 1 mà nó vẫn chạy đúng nhưng của anh nếu không trừ 1 thì sẽ báo lỗi ngay.
 
Upvote 0
- Cái chỗ ReDim dArr(1 To UBound(sArr, 1) - 1, 1 To 34)
Chắc là để loại bỏ N/A mà không phải trừ 1 phần tử khi gán mảng dArr phải không anh?

- Vậy thì đoạn này: Dic.Item(CStr(sArr(I, 1))) = I - 1 tại sao phải trừ 1? Code của em không trừ 1 mà nó vẫn chạy đúng nhưng của anh nếu không trừ 1 thì sẽ báo lỗi ngay.
sArr lấy từ dòng 6, dArr lấy từ dòng 7,nên số dòng của dArr ít hơn sArr 1 dòng, nên khai báo dArr:
ReDim dArr(1 To UBound(sArr, 1) - 1, 1 To 34)

For I = 2 To UBound(sArr, 1)
If Len(sArr(I, 1)) > 0 Then
Dic.Item(CStr(sArr(I, 1))) = I - 1
End If
Next I

Vòng lặp bắt đầu i=2, dArr bắt đầu từ 1, nên I-1 là thứ tự dòng của dArr

Để tường minh hơn và nhẹ code, bạn chỉnh code lại như sau
Mã:
With Sheets("Tong hop cong")
   If CStr(.Range("C7")) <> "" Then
       .Range("C8:BP7000").ClearContents
   End If
   sArr = .Range("B6").Resize(, 34).Value 'lay cot ngay
   For J = 4 To 34
       If sArr(1, J) <> Empty Then
           If IsDate(sArr(1, J)) Then Col.Item(Day(sArr(1, J))) = J
       End If
   Next J
   sArr = .Range("B7", .Range("B65000").End(xlUp)).Value 'lay dong
   ReDim dArr(1 To UBound(sArr, 1), 1 To 34)
   For I = 1 To UBound(sArr, 1)
       If Len(sArr(I, 1)) > 0 Then
           Dic.Item(CStr(sArr(I, 1))) = I 
       End If
   Next I
End With


 
Upvote 0
Nhờ các bác viết giúp mình 1 code vba.
1. khi click vào nút THVT từ sheet xuatDL thì vật tư ( VL, NC, M) được lọc và xuất sang sheet THVT như ví dụ ở sheet THVT.
A) Vật liệu:
xi măng
.........
B)Nhán công
Nhân công
C)Máy thi công
M:...........
 

File đính kèm

  • VD2.xls
    889 KB · Đọc: 7
Upvote 0
Nhờ các bác viết giúp mình 1 code vba.
1. khi click vào nút THVT từ sheet xuatDL thì vật tư ( VL, NC, M) được lọc và xuất sang sheet THVT như ví dụ ở sheet THVT.
A) Vật liệu:
xi măng
.........
B)Nhán công
Nhân công
C)Máy thi công
M:...........
Bạn chạy Sub này thử
PHP:
Sub Tonghopvattu()
Application.ScreenUpdating = False
    Dim Dic As Object, Tem As String
    Dim sArr(), dArr(), tArr(), Er As Long
    Dim I As Long, J As Long, N As Long, K As Long, LaMa As Long, Stt As Long, Rws As Long
Set Dic = CreateObject("scripting.Dictionary")
With Sheets("xuatDL")
    sArr = .Range("C7", .Range("C65536").End(3)).Resize(, 5).Value
    tArr = .Range("L1:N1").Value
End With
ReDim dArr(1 To UBound(sArr, 1), 1 To 5)
With Sheets("THVT")
    With .Range("A6:I1000")
        .ClearContents: .Interior.ColorIndex = 0: .Borders.LineStyle = 0: .Font.Bold = False
    End With
    For N = 1 To 3
        Stt = 0:        LaMa = LaMa + 1:        K = K + 1
        dArr(K, 1) = ChrW(LaMa + 64): dArr(K, 2) = tArr(1, N)
        .Range("A" & K + 5).Resize(, 9).Interior.ColorIndex = 20
        .Range("A" & K + 5).Resize(, 9).Font.Bold = True
        For I = 1 To UBound(sArr, 1)
            If sArr(I, 1) <> Empty Then
                If Left(sArr(I, 1), 1) = Left(tArr(1, N), 1) Then
                    Tem = sArr(I, 1)
                    If Not Dic.Exists(Tem) Then
                        K = K + 1: Stt = Stt + 1
                        Dic.Add Tem, K
                        dArr(K, 1) = Stt:           dArr(K, 2) = sArr(I, 1)
                        dArr(K, 3) = sArr(I, 2):    dArr(K, 4) = sArr(I, 3)
                        dArr(K, 5) = sArr(I, 5)
                    Else
                        Rws = Dic.Item(Tem): dArr(Rws, 5) = dArr(Rws, 5) + sArr(I, 5)
                    End If
                End If
            End If
        Next I
    Next N
    .Range("A6").Resize(K, 5) = dArr:
    .Range("A6").Resize(K, 9).Borders.LineStyle = 1
    If Not IsNumeric(.Range("A65536").End(3)) Then .Range("A65536").End(3).EntireRow.Delete
    Er = .Range("A65536").End(3).Row
    For I = Er To 6 Step -1
        If Not IsNumeric(.Range("A" & I)) Then
            .Range("B" & I + 1 & ":I" & Er).Sort Key1:=.Range("C" & I + 1)
            Er = I - 1
        End If
    Next I
End With
Set Dic = Nothing
End Sub
 
Upvote 0
Bạn chạy Sub này thử
PHP:
Sub Tonghopvattu()
Application.ScreenUpdating = False
    Dim Dic As Object, Tem As String
    Dim sArr(), dArr(), tArr(), Er As Long
    Dim I As Long, J As Long, N As Long, K As Long, LaMa As Long, Stt As Long, Rws As Long
Set Dic = CreateObject("scripting.Dictionary")
With Sheets("xuatDL")
    sArr = .Range("C7", .Range("C65536").End(3)).Resize(, 5).Value
    tArr = .Range("L1:N1").Value
End With
ReDim dArr(1 To UBound(sArr, 1), 1 To 5)
With Sheets("THVT")
    With .Range("A6:I1000")
        .ClearContents: .Interior.ColorIndex = 0: .Borders.LineStyle = 0: .Font.Bold = False
    End With
    For N = 1 To 3
        Stt = 0:        LaMa = LaMa + 1:        K = K + 1
        dArr(K, 1) = ChrW(LaMa + 64): dArr(K, 2) = tArr(1, N)
        .Range("A" & K + 5).Resize(, 9).Interior.ColorIndex = 20
        .Range("A" & K + 5).Resize(, 9).Font.Bold = True
        For I = 1 To UBound(sArr, 1)
            If sArr(I, 1) <> Empty Then
                If Left(sArr(I, 1), 1) = Left(tArr(1, N), 1) Then
                    Tem = sArr(I, 1)
                    If Not Dic.Exists(Tem) Then
                        K = K + 1: Stt = Stt + 1
                        Dic.Add Tem, K
                        dArr(K, 1) = Stt:           dArr(K, 2) = sArr(I, 1)
                        dArr(K, 3) = sArr(I, 2):    dArr(K, 4) = sArr(I, 3)
                        dArr(K, 5) = sArr(I, 5)
                    Else
                        Rws = Dic.Item(Tem): dArr(Rws, 5) = dArr(Rws, 5) + sArr(I, 5)
                    End If
                End If
            End If
        Next I
    Next N
    .Range("A6").Resize(K, 5) = dArr:
    .Range("A6").Resize(K, 9).Borders.LineStyle = 1
    If Not IsNumeric(.Range("A65536").End(3)) Then .Range("A65536").End(3).EntireRow.Delete
    Er = .Range("A65536").End(3).Row
    For I = Er To 6 Step -1
        If Not IsNumeric(.Range("A" & I)) Then
            .Range("B" & I + 1 & ":I" & Er).Sort Key1:=.Range("C" & I + 1)
            Er = I - 1
        End If
    Next I
End With
Set Dic = Nothing
End Sub
Cám ơn chị rất nhiều. chị có thể chỉnh sửa bài #1245 giúp e được không?
Chuyên mục xử lý, gỡ rối code VBA
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn chạy Sub này thử
PHP:
Sub Tonghopvattu()
Application.ScreenUpdating = False
    Dim Dic As Object, Tem As String
    Dim sArr(), dArr(), tArr(), Er As Long
    Dim I As Long, J As Long, N As Long, K As Long, LaMa As Long, Stt As Long, Rws As Long
Set Dic = CreateObject("scripting.Dictionary")
With Sheets("xuatDL")
    sArr = .Range("C7", .Range("C65536").End(3)).Resize(, 5).Value
    tArr = .Range("L1:N1").Value
End With
ReDim dArr(1 To UBound(sArr, 1), 1 To 5)
With Sheets("THVT")
    With .Range("A6:I1000")
        .ClearContents: .Interior.ColorIndex = 0: .Borders.LineStyle = 0: .Font.Bold = False
    End With
    For N = 1 To 3
        Stt = 0:        LaMa = LaMa + 1:        K = K + 1
        dArr(K, 1) = ChrW(LaMa + 64): dArr(K, 2) = tArr(1, N)
        .Range("A" & K + 5).Resize(, 9).Interior.ColorIndex = 20
        .Range("A" & K + 5).Resize(, 9).Font.Bold = True
        For I = 1 To UBound(sArr, 1)
            If sArr(I, 1) <> Empty Then
                If Left(sArr(I, 1), 1) = Left(tArr(1, N), 1) Then
                    Tem = sArr(I, 1)
                    If Not Dic.Exists(Tem) Then
                        K = K + 1: Stt = Stt + 1
                        Dic.Add Tem, K
                        dArr(K, 1) = Stt:           dArr(K, 2) = sArr(I, 1)
                        dArr(K, 3) = sArr(I, 2):    dArr(K, 4) = sArr(I, 3)
                        dArr(K, 5) = sArr(I, 5)
                    Else
                        Rws = Dic.Item(Tem): dArr(Rws, 5) = dArr(Rws, 5) + sArr(I, 5)
                    End If
                End If
            End If
        Next I
    Next N
    .Range("A6").Resize(K, 5) = dArr:
    .Range("A6").Resize(K, 9).Borders.LineStyle = 1
    If Not IsNumeric(.Range("A65536").End(3)) Then .Range("A65536").End(3).EntireRow.Delete
    Er = .Range("A65536").End(3).Row
    For I = Er To 6 Step -1
        If Not IsNumeric(.Range("A" & I)) Then
            .Range("B" & I + 1 & ":I" & Er).Sort Key1:=.Range("C" & I + 1)
            Er = I - 1
        End If
    Next I
End With
Set Dic = Nothing
End Sub
Các bạn và bạn PacificPR giúp mình thêm code này nữa nhé!
1. khi click nút link thì cột H (đơn giá) của sheet xuatDL được kết nối từ sheet THVT, sau đó sum của VL, NC, máy sẽ được link sang sheet KHOILUONG
2. Từ sheet THVT bạn có thể xuất số liệu của phần vật liệu sang sheet VAT LIEU, mỗi vật liệu cách nhau 5 dòng. Thank!
 

File đính kèm

  • VD1.xls
    3.3 MB · Đọc: 3
Upvote 0
Các bạn và bạn PacificPR giúp mình thêm code này nữa nhé!
1. khi click nút link thì cột H (đơn giá) của sheet xuatDL được kết nối từ sheet THVT, sau đó sum của VL, NC, máy sẽ được link sang sheet KHOILUONG
2. Từ sheet THVT bạn có thể xuất số liệu của phần vật liệu sang sheet VAT LIEU, mỗi vật liệu cách nhau 5 dòng. Thank!
Hình như cái File này em đã gặp ở đâu trên diễn đàn mình roài thì phải. (Hình như bài của anh "Sơn thủ bạc"):D
 
Upvote 0
Các bạn và bạn PacificPR giúp mình thêm code này nữa nhé!
1. khi click nút link thì cột H (đơn giá) của sheet xuatDL được kết nối từ sheet THVT, sau đó sum của VL, NC, máy sẽ được link sang sheet KHOILUONG
2. Từ sheet THVT bạn có thể xuất số liệu của phần vật liệu sang sheet VAT LIEU, mỗi vật liệu cách nhau 5 dòng. Thank!
có ai không, giúp mình với đi
 
Upvote 0

File đính kèm

  • Hoi Code VBA 8.xls
    161 KB · Đọc: 4
Upvote 0
Nhờ các bạn chỉnh sửa code giúp mình:
1. Mình muốn chuyển cột j trong sheet "xuatDL" thành hàm PRODUCT(G11:I11)
2. Các hàng a) vật liệu, b)NC, C)Máy tại cột J tô đậm được ko?. Thank!
 

File đính kèm

  • VD1.xls
    3.8 MB · Đọc: 9
Upvote 0
Chào mọi người,

Mình có 1 file excel như ở dưới. Hiện tại mình đang không biết dùng hàm gì để có thể tính được Doanh Số theo ngày ở Sheet Doanh Số. Về cơ bản thì Doanh Số của một ngày được tính bằng Doanh Số của tất cả các mặt hàng (Khoảng 800 mặt hàng tương đương với khoảng 800 sheets) bán được trong ngày đấy, và Doanh Số của một mặt hàng thì bằng số lượng mỗi nhân viên bán được trong ngày hôm đấy( Hùng, Hiếu, Thắng và Lẻ) nhân với giá của mặt hàng ở một sheet khác. Mình đã thử làm cách thủ công mà không được nên mình đang đọc và tìm hiểu về VBA, mong mọi người giúp mình xem nên dùng giải quyết được vấn đề tìm dữ liệu trong nhiều sheets và vòng lặp như thế nào.

Mình cảm ơn rất nhiều.
Do file nặng quá nên mình up lên googledriver: https://drive.google.com/open?id=1gPoxaJuKrkPth0XEIW1T-7cDFykfrQ5Y
 
Upvote 0
Chào các bạn,
Mình tạo marco này để chuyển dữ liệu từ Sheet3 sang dạng Pivot Table và Tabular Form. Các bước như sau:
- Ctrl + Shift từ cột A tới cột H (số liệu sẽ cập nhật tiếp tục theo dòng) trong Sheet3
- Chọn tab Insert, chọn Pivot Table và tạo Pivot Table sang 1 sheet khác
- Sau khi tạo Pivot Table, ấn vào đó, để hiện lên PivotTable Tools => chọn tab Design => chọn không hiện Subtotals và Grand Totals trên báo cáo, và ấn vào Report Layout, chọn Show in Tabular Form.
- Lưu macro và chạy thử, báo lỗi.

Mình xin gửi file dữ liệu đây. Xin nhờ các chuyên gia chỉ dẫn sửa code VBA để chạy macro này.

Mình xin cảm ơn nhiều! :)
 

File đính kèm

  • LL- bao cao dat hang-2.xlsm
    30.6 KB · Đọc: 2
Upvote 0
Mã:
Private Sub cmdThem_Click()
    Dim Lr As Long, stt As Long
 
    Lr = Sheet7.Cells(Rows.Count, "B").End(3).Row
 
    If Me.cmbMaTS = "" Then
        MsgBox ("Ban chua chon kieu ma tai san")
        Me.cmbMaTS.SetFocus
        Exit Sub
    End If
    If Me.txtMaTS = "" Then
        MsgBox ("Ban chua nhap ma tai san")
        Me.txtMaTS.SetFocus
        Exit Sub
    End If
    With Sheet7
 
 
    stt = Application.WorksheetFunction.CountIf(.Range("$B$2:B" & Lr), Me.cmbMaTS.Value & " * ")
 
    Select Case stt
            Case Is < 10
                .Range("B" & Lr + 1) = StrConv(cmbMaTS.Value & Me.txtMaTS.Value & "00" & stt + 1, vbUpperCase)
            Case Is < 100
                .Range("B" & Lr + 1) = StrConv(cmbMaTS.Value & Me.txtMaTS.Value & "0" & stt + 1, vbUpperCase)
            Case Else
                .Range("B" & Lr + 1) = StrConv(cmbMaTS.Value & Me.txtMaTS.Value & stt + 1, vbUpperCase)
    End Select
    End With
End Sub
Xin chỉ giúp mình đở đoạn code
Mã:
stt = Application.WorksheetFunction.CountIf(.Range("$B$2:B" & Lr), Me.cmbMaTS.Value & " * ")
Stt nó không đánh được số thứ tự theo mã ở cmbMaTS nhỉ.b
Mục đích của mình tạo ra mã hàng theo cmbMaTS & txtMaTS và STT theo cmbMaTS
 

File đính kèm

  • file V2.1.3.xlsm
    190.6 KB · Đọc: 3
Lần chỉnh sửa cuối:
Upvote 0
Xem giúp em code này ạ

Sub clean()
On Error Resume Next
Dim arr, arr1, res, res1, i As Long, j As Long, k As Long, k1 As Long
With Sheets("Du lieu vao")
arr = .Range(.[A10], .[A65000].End(xlUp)).Resize(, 22).Value
arr1 = .Range(.[X10], .[X65000].End(xlUp)).Resize(, 2).Value
ReDim res(1 To UBound(arr, 1), 1 To 22)
ReDim res1(1 To UBound(arr, 1), 1 To 2)
For i = 1 To UBound(arr, 1)
If DateAdd("m", 13, arr(i, 1)) >= Date Then
k = k + 1
For j = 1 To 22
res(k, j) = arr(i, j)
Next j
End If
Next i
For i = 1 To UBound(arr1, 1)
If DateAdd("m", 13, arr1(i, 1)) >= Date Then
k1 = k1 + 1
res1(k1, 1) = arr1(i, 1)
res1(k1, 2) = arr1(i, 2)
End If
Next i
.Range("A10:Y10000").ClearContents
If k Then .Range("A10").Resize(k, 22).Value = res
If k1 Then .Range("X10").Resize(k1, 2).Value = res1
End With
End Sub

Nếu dữ liệu cột X,Y có số dòng dài hơn dữ liệu cột A:V thì phần dài hơn sẽ bị lỗi N/A. Em cảm ơn
 

File đính kèm

  • sua loi.xlsm
    547.1 KB · Đọc: 3
Upvote 0
Xem giúp em code này ạ

Sub clean()
On Error Resume Next
Dim arr, arr1, res, res1, i As Long, j As Long, k As Long, k1 As Long
With Sheets("Du lieu vao")
arr = .Range(.[A10], .[A65000].End(xlUp)).Resize(, 22).Value
arr1 = .Range(.[X10], .[X65000].End(xlUp)).Resize(, 2).Value
ReDim res(1 To UBound(arr, 1), 1 To 22)
ReDim res1(1 To UBound(arr, 1), 1 To 2)
For i = 1 To UBound(arr, 1)
If DateAdd("m", 13, arr(i, 1)) >= Date Then
k = k + 1
For j = 1 To 22
res(k, j) = arr(i, j)
Next j
End If
Next i
For i = 1 To UBound(arr1, 1)
If DateAdd("m", 13, arr1(i, 1)) >= Date Then
k1 = k1 + 1
res1(k1, 1) = arr1(i, 1)
res1(k1, 2) = arr1(i, 2)
End If
Next i
.Range("A10:Y10000").ClearContents
If k Then .Range("A10").Resize(k, 22).Value = res
If k1 Then .Range("X10").Resize(k1, 2).Value = res1
End With
End Sub

Nếu dữ liệu cột X,Y có số dòng dài hơn dữ liệu cột A:V thì phần dài hơn sẽ bị lỗi N/A. Em cảm ơn
Bạn thêm vào 2 dòng lệnh sau, nếu đặt biến ngay từ đầu thì tốt hơn (t = Ubound(...))

Mã:
   For i = 1 To UBound(arr1, 1)
     If i < UBound(arr, 1) + 1 Then '<=== Them vao
     If DateAdd("m", 13, arr1(i, 1)) >= Date Then
        k1 = k1 + 1
        res1(k1, 1) = arr1(i, 1)
        res1(k1, 2) = arr1(i, 2)
     End If
     End If                            '<=== Them vao
   Next i
 
Upvote 0
Bạn thêm vào 2 dòng lệnh sau, nếu đặt biến ngay từ đầu thì tốt hơn (t = Ubound(...))

Mã:
   For i = 1 To UBound(arr1, 1)
     If i < UBound(arr, 1) + 1 Then '<=== Them vao
     If DateAdd("m", 13, arr1(i, 1)) >= Date Then
        k1 = k1 + 1
        res1(k1, 1) = arr1(i, 1)
        res1(k1, 2) = arr1(i, 2)
     End If
     End If                            '<=== Them vao
   Next i
Bác ơi, vậy trong trường hợp i>ubound(arr,1) thì làm thế nào?
 
Upvote 0
Status
Không mở trả lời sau này.
Web KT
Back
Top Bottom