Nhờ các cao thủ VBA giúp tách riêng tiền Vật liệu, nhân công, máy

Liên hệ QC

Phanhanhdai

Thành viên tiêu biểu
Tham gia
16/3/08
Bài viết
733
Được thích
1,876
Nghề nghiệp
Thiết kế công trình
Em có bảng đơn giá chi tiết, vấn đề em muốn tại cột thành tiền ứng với mỗi công việc có tách được tiền vật liệu, nhân công và máy ra (sử dụng VBA tham chiếu hiện công thức dưới dạng Fomular hoặc Funtion càng tốt). Bảng của em dài nếu lần nào cũng Sum bằng tay thì sẽ rất mất thời gian. Chân thành mong được các anh, chị quan tâm, giúp đỡ./.
 

File đính kèm

Đua tốc độ --=0
Code này có lẽ nhanh hơn đấy.
PHP:
Sub TinhTong()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
R1 = [C65536].End(xlUp).Row
For i = [C65536].End(xlUp).Row To 6 Step -1
If Cells(i, 3) = "" Then
    Range("H" & i).Formula = Replace("=SUM(" &  _
           Cells(i + 1, 8).Address & ":" & Cells(R1, 8).Address & ")", "$", "")
    R1 = i - 1
    ElseIf Cells(i, 6) > 0 Then
    Range("H" & i).FormulaR1C1 = "=RC[-3]*RC[-2]"
End If
R1 = R1 - IIf(Cells(i, 1) <> "", 1, 0)
Next
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Tôi không rành về XDCB nên không thể dựa vào DVT của các thành phần mà tính được.
Đúng là đoạn thừa đấy. Từ khóa rất nhiều, nhiều khi không nhớ hết. Vì vậy đôi khi cần phải sử dụng chức năng Record Macro.
Bây giờ em muốn thêm tại mỗi công việc thì tổng tiền vật liệu, nhân công và máy là bao nhiêu tiền (điền ngay tại cột H, cùng dòng với tên công việc) thì em phải làm thể nào? Mong bác chỉ bảo cho
 
Upvote 0
Bây giờ em muốn thêm tại mỗi công việc thì tổng tiền vật liệu, nhân công và máy là bao nhiêu tiền (điền ngay tại cột H, cùng dòng với tên công việc) thì em phải làm thể nào? Mong bác chỉ bảo cho
Vậy thì sửa lại một chút. Như thế này:
PHP:
Sub TinhTong()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
R1 = [C65536].End(xlUp).Row
R2 = R1
For i = [C65536].End(xlUp).Row To 6 Step -1
If Cells(i, 3) = "" Then
    Range("H" & i).Formula = "=SUM(" & _
           Cells(i + 1, 8).Address(0, 0) & ":" & Cells(R1, 8).Address(0, 0) & ")"
    R1 = i - 1
    ElseIf Cells(i, 6) > 0 Then
    Range("H" & i).FormulaR1C1 = "=RC[-3]*RC[-2]"
End If
If Cells(i, 1) <> "" Then
    R1 = R1 - 1
    Range("H" & i).Formula = "=SUM(" & _
           Cells(i + 1, 8).Address(0, 0) & ":" & Cells(R2, 8).Address(0, 0) & ")/2"
    R2 = i - 1
End If
Next
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
 
Upvote 0
Vậy thì sửa lại một chút. Như thế này:
PHP:
Sub TinhTong()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
R1 = [C65536].End(xlUp).Row
R2 = R1
For i = [C65536].End(xlUp).Row To 6 Step -1
If Cells(i, 3) = "" Then
    Range("H" & i).Formula = "=SUM(" & _
           Cells(i + 1, 8).Address(0, 0) & ":" & Cells(R1, 8).Address(0, 0) & ")"
    R1 = i - 1
    ElseIf Cells(i, 6) > 0 Then
    Range("H" & i).FormulaR1C1 = "=RC[-3]*RC[-2]"
End If
If Cells(i, 1) <> "" Then
    R1 = R1 - 1
    Range("H" & i).Formula = "=SUM(" & _
           Cells(i + 1, 8).Address(0, 0) & ":" & Cells(R2, 8).Address(0, 0) & ")/2"
    R2 = i - 1
End If
Next
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Em lại xin được mong anh chỉ giúp em. Công việc của em giả sử yêu cầu cuối mỗi công việc tự động chèn một dòng. (Nội dung cột C dòng chèn đó có tên là Chi phí xây dựng trước thuế; cột thành tiền được xác định bằng kết quả VL+NC+M được xác định vừa rồi nhân với hệ số 1,1 tức đã có thuế giá trị gia tăng). Rất mong sự giúp đỡ của anh
 
Upvote 0
Em lại xin được mong anh chỉ giúp em. Công việc của em giả sử yêu cầu cuối mỗi công việc tự động chèn một dòng. (Nội dung cột C dòng chèn đó có tên là Chi phí xây dựng trước thuế; cột thành tiền được xác định bằng kết quả VL+NC+M được xác định vừa rồi nhân với hệ số 1,1 tức đã có thuế giá trị gia tăng). Rất mong sự giúp đỡ của anh
Đây là code theo yêu cầu mới của bạn.
PHP:
Sub TinhTong()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Range([A8], [C65536].End(xlUp).Offset(, -2)).SpecialCells(xlCellTypeConstants, 23).EntireRow.Insert
R1 = [C65536].End(xlUp).Row
R2 = R1 + 1
For i = [C65536].End(xlUp).Row + 1 To 6 Step -1
If Cells(i, 3) = "" And Cells(i, 2) <> "" Then
    Range("H" & i).Formula = "=SUBTOTAL(9," & _
           Cells(i + 1, 8).Address(0, 0) & ":" & Cells(R1, 8).Address(0, 0) & ")"
    R1 = i - 1
    ElseIf Cells(i, 6) > 0 Then
    Range("H" & i).FormulaR1C1 = "=RC[-3]*RC[-2]"
End If
If Cells(i, 1) = "" And Cells(i, 2) = "" Then
    Cells(i, 2) = "Chi phÝ x©y dùng tr­íc thuÕ"
    R2 = i
    ElseIf Cells(i, 1) <> "" Then
    R1 = R1 - 2
    Range("H" & R2).Formula = "=SUBTOTAL(9," & _
           Cells(i + 1, 8).Address(0, 0) & ":" & Cells(R2 - 1, 8).Address(0, 0) & ")*1.1"
End If
Next
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Bạn chý ý. Lần sau nên đưa ra yêu cầu cuối cùng ngay từ đầu, đừng nên dắt mọi người đi theo từng bước của bạn. Mất thời gian của người khác và của cả bạn nữa.
 
Upvote 0
Đua tốc độ --=0
Code này có lẽ nhanh hơn đấy.
.
Anh cho em hỏi nếu có người nào nghịch chèn thêm một dòng vật liệu tại một công tác bất kỳ (tức là xuất hiện hai dòng vật liệu liên tiếp như tại dòng 14,15) thì ta phải xử lý thế nào ạh.
 

File đính kèm

Upvote 0
Nếu có người nào chèn thêm một dòng vật liệu tại một công tác bất kỳ (tức là xuất hiện hai dòng vật liệu liên tiếp như tại dòng 14,15) thì ta phải xử lý thế nào ạh.

Tại bài #6 ta có đoạn macro:
Mã:
12      [COLOR=#007700]Else [/COLOR]
[COLOR=#007700]        If [/COLOR][COLOR=#0000bb]sRng[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]Offset[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]2[/COLOR][COLOR=#007700]) = [/COLOR][COLOR=#dd0000]"" [/COLOR][COLOR=#0000bb]Then [/COLOR]
[COLOR=#0000bb]           Rw [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]1[/COLOR][COLOR=#007700]:              [/COLOR][COLOR=#0000bb]sRng[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]Offset[/COLOR][COLOR=#007700](, [/COLOR][COLOR=#0000bb]5[/COLOR][COLOR=#007700]).[/COLOR][COLOR=#0000bb]Font[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]ColorIndex [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]3 [/COLOR]
[COLOR=#007700]Else [/COLOR]
Ta phải sửa lại là:
PHP:
12      Else 
         If  sRng.Offset(1) = "" Then  '< Mới thêm|'
         ElseIf sRng.Offset(2) = "" Then 
            Rw = 1:              sRng.Offset(, 5).Font.ColorIndex = 3 
         Else
 
Upvote 0
Anh cho em hỏi nếu có người nào nghịch chèn thêm một dòng vật liệu tại một công tác bất kỳ (tức là xuất hiện hai dòng vật liệu liên tiếp như tại dòng 14,15) thì ta phải xử lý thế nào ạh.
Code hay công thức gì cũng dựa trên cơ sở dữ liệu ban đầu. Nó phải có một cái chuẩn nào đó. Và tôi nghĩ không nên đầu tư công sức vào những trường hợp "lỡ như" như vậy. Muốn sử dụng code thì phải đưa dữ liệu về chuẩn. Còn nếu muốn nghịch dại thì sẽ phải tự chịu trách nhiệm về kết quả thôi.
 
Upvote 0
Vậy thì sửa lại một chút. Như thế này:
PHP:
........
If Cells(i, 1) <> "" Then
    R1 = R1 - 1
    Range("H" & i).Formula = "=SUM(" & _
           Cells(i + 1, 8).Address(0, 0) & ":" & Cells(R2, 8).Address(0, 0) & ")/2"
    R2 = i - 1
End Sub
Dòng lệnh trên chia 2 nhằm mục đích do tính trùng lặp 2 lần, nhưng nếu giá như mà tại ô kết quả nó chỉ hiện ra được tham chiếu theo ô vật liệu + nhân công mà bỏ qua những ô thành phần thì đỡ phải chia đôi. Mình có thể làm thế đỡ phải chia đôi (tức là em muốn Sếp kiểm tra nhìn nó trực quan hơn) có được không anh?
 
Upvote 0
Dòng lệnh trên chia 2 nhằm mục đích do tính trùng lặp 2 lần, nhưng nếu giá như mà tại ô kết quả nó chỉ hiện ra được tham chiếu theo ô vật liệu + nhân công mà bỏ qua những ô thành phần thì đỡ phải chia đôi. Mình có thể làm thế đỡ phải chia đôi (tức là em muốn Sếp kiểm tra nhìn nó trực quan hơn) có được không anh?
Sửa lại cho bạn nè:
PHP:
Sub TinhTong()
Dim R1 As Long, R2 As Long, F As String
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Range([A8], [C65536].End(xlUp).Offset(, -2)).SpecialCells(xlCellTypeConstants, 23).EntireRow.Insert
R1 = [C65536].End(xlUp).Row
R2 = R1 + 1
F = ""
For i = [C65536].End(xlUp).Row + 1 To 6 Step -1
If Cells(i, 3) = "" And Cells(i, 2) <> "" Then
    Range("H" & i).Formula = "=SUM(" & _
           Cells(i + 1, 8).Address(0, 0) & ":" & Cells(R1, 8).Address(0, 0) & ")"
    R1 = i - 1
    F = F & Cells(i, 8).Address(0, 0) & " "
    ElseIf Cells(i, 6) > 0 Then
    Range("H" & i).FormulaR1C1 = "=RC[-3]*RC[-2]"
End If
If Cells(i, 1) = "" And Cells(i, 2) = "" Then
    Cells(i, 2) = "Chi phÝ x©y dùng tr­íc thuÕ"
    R2 = i
    ElseIf Cells(i, 1) <> "" Then
    R1 = R1 - 2
    Range("H" & R2).Formula = "=(" & Replace(Trim(F), " ", "+") & ")*1.1"
    F = ""
End If
Next
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
 
Upvote 0
Đến đây bắt đầu phức tạp rồi. Quả thực kiến thức của anh siêu quá em theo không kịp, em chưa hình dung ra biến F đưa vào có ý nghĩa gì. Mong anh giải thích sơ bộ qua biến F này và 2 dòng sau để em hình dung ra được:
[FONT=.VnTime] F = F & Cells(i, 8).Address(0, 0) & " "[/FONT]
[FONT=.VnTime] Range("H" & R2).Formula = "=(" & Replace(Trim(F), " ", "+") & ")*1.1"
[/FONT]
 
Upvote 0
Đến đây bắt đầu phức tạp rồi. Quả thực kiến thức của anh siêu quá em theo không kịp, em chưa hình dung ra biến F đưa vào có ý nghĩa gì. Mong anh giải thích sơ bộ qua biến F này và 2 dòng sau để em hình dung ra được:
[FONT=.VnTime] F = F & Cells(i, 8).Address(0, 0) & " "[/FONT]
[FONT=.VnTime] Range("H" & R2).Formula = "=(" & Replace(Trim(F), " ", "+") & ")*1.1"
[/FONT]
Cho vòng lặp duyệt từ dưới lên
Nếu dòng nào có cột C = "" và cột B <> "" ( tức là vật liệu, nhân công hoặc máy thi công)
Lúc này Cells(i,8) là ô tính tổng của từng nhóm vật liệu, nhân công hoặc máy thi công
Gán F = F & Cells(i,8).Address(0,0) & " "
Cells(i,8).Address(0,0) là địa chỉ của ô tổng vật liệu, nhân công hoặc máy thi công.
Ví dụ:
Gặp ô nhân công ở i = 550 thì gán
F = F & Cells(i,8).Address(0,0) & " " = "H550 "
Gặp tiếp ô vật liệu ở i = 547 thì gán
F = F & Cells(i,8).Address(0,0) & " " = "H550 H547 "
Trong đoạn này
PHP:
If Cells(i, 1) = "" And Cells(i, 2) = "" Then
    Cells(i, 2) = "Chi phÝ x©y dùng tr­íc thuÕ"
    R2 = i
    ElseIf Cells(i, 1) <> "" Then
    R1 = R1 - 2
    Range("H" & R2).Formula = "=(" & Replace(Trim(F), " ", "+") & ")*1.1"
    F = ""
End If
Thì
PHP:
If Cells(i, 1) = "" And Cells(i, 2) = "" Then
    Cells(i, 2) = "Chi phÝ x©y dùng tr­íc thuÕ"
    R2 = i
Là nếu gặp dòng nào có cột A = "" và cột B = "" nghĩa là dòng trống, các dòng mới chèn thì Nhập vào cột B: Chi phí xây dựng trước thuế.
Đoạn này
PHP:
ElseIf Cells(i, 1) <> "" Then
    R1 = R1 - 2
    Range("H" & R2).Formula = "=(" & Replace(Trim(F), " ", "+") & ")*1.1"
    F = ""
Nếu cột A <> "" (là các dòng đầu tiên của mỗi công việc) thì
PHP:
Range("H" & R2).Formula = "=(" & Replace(Trim(F), " ", "+") & ")*1.1"
Điền công thức vào ô ở cột H dòng R2
Trim(F) là loại các ký tự " " thừa. Ví dụ lúc này có F = "H550 H547 " thì Trim(F) = "H550 H547"
Replace(Trim(F), " ", "+") là thay các ký tự " " bằng các ký tự "+". Ta được "H550+H547"
"=(" & Replace(Trim(F), " ", "+") & ")*1.1" ta được "=(H550+H547)*1.1"
Gán nó vào công thức ô ở cột H dòng R2
PHP:
F = ""
Gán F = "" để bắt đầu lại từ đầu.
 
Upvote 0
Xin anh chỉ cho cách chèn 2 dòng lên trên đầu mục công việc

Cảm ơn anh đã chỉ bảo, em cũng phần nào học hỏi được, em đang thử hình dung và làm thử một số bài tập tương tự để có thể ứng dụng các phần khác. Em xin hỏi bác thêm nữa là nếu muốn tự đồng chèn 2 dòng hoặc 3 dòng (chứ không phải là một dòng như các bài trước) lên trên dòng số có đánh thứ tự các công việc tại cột A thì phải làm thế nào, xin bác có thể tiếp tục giúp để em có thể học hỏi thêm./.
 
Upvote 0
Cảm ơn anh đã chỉ bảo, em cũng phần nào học hỏi được, em đang thử hình dung và làm thử một số bài tập tương tự để có thể ứng dụng các phần khác. Em xin hỏi bác thêm nữa là nếu muốn tự đồng chèn 2 dòng hoặc 3 dòng (chứ không phải là một dòng như các bài trước) lên trên dòng số có đánh thứ tự các công việc tại cột A thì phải làm thế nào, xin bác có thể tiếp tục giúp để em có thể học hỏi thêm./.
Thay
PHP:
Range([A8], [C65536].End(xlUp).Offset(, -2)).SpecialCells(xlCellTypeConstants, 23).EntireRow.Insert
Bằng
PHP:
With Range([A8], [C65536].End(xlUp).Offset(, -2)).SpecialCells(xlCellTypeConstants, 23).EntireRow.
.Insert
.Insert
.Insert
End With
Insert 3, 4 lần đó gì tùy bạn.
 
Upvote 0
Lấy số liệu không cùng dòng của từng công việc sang sheet khác

Em lại xin được mong anh chỉ giúp em. Công việc của em giả sử yêu cầu cuối mỗi công việc tự động chèn một dòng. (Nội dung cột C dòng chèn đó có tên là Chi phí xây dựng trước thuế; cột thành tiền được xác định bằng kết quả VL+NC+M được xác định vừa rồi nhân với hệ số 1,1 tức đã có thuế giá trị gia tăng). Rất mong sự giúp đỡ của anh
Em lại xin nhờ bác chút nữa, nếu bây giờ em muốn tự động lấy tên công việc, đơn vị tính của đơn vị ấy, đặc biệt là lấy giá trị cột H (của dòng Chi phí xây dựng trước thuế) tương ứng với công việc ấy sang một sheet mới mà vẫn đảm bảo được giữ nguyên tham chiếu (Formular) với Sheet cũ thì ta làm thế nào (Tức là mỗi công việc sang sheet mới ta cần đảm bảo tên công việc & giá trị trước thuế thể hiện trên cùng dòng tại Sheet mới đó)
 
Lần chỉnh sửa cuối:
Upvote 0
Em lại xin nhờ bác chút nữa, nếu bây giờ em muốn tự động lấy tên công việc, đơn vị tính của đơn vị ấy, đặc biệt là lấy giá trị cột H (của dòng Chi phí xây dựng trước thuế) tương ứng với công việc ấy sang một sheet mới mà vẫn đảm bảo được giữ nguyên tham chiếu (Formular) với Sheet cũ thì ta làm thế nào (Tức là mỗi công việc sang sheet mới ta cần đảm bảo tên công việc & giá trị trước thuế thể hiện trên cùng dòng tại Sheet mới đó)
Chạy Sub TinhTong trước, sau đó chạy Sub TongHop.
 

File đính kèm

Upvote 0
Đến bây giờ nhờ tham khảo các code của bác em đã tự thực hiện được nhiều vấn đề của mình. Xin chân thành cảm ơn anh rất nhiều. Nhưng em đang nghĩ nếu em tự động chèn 2 dòng (thay vì một dòng như trước bài mẫu của mình là If Cell (i,1)=""And Cells (i,2)=""Then Cells(i,2)="Chi phí xây dựng trước thuế) trước tên của mỗi công việc tại cột A, thì tại mỗi công việc sẽ xuất hiện hai dòng trống. Như vậy làm thế nào cho máy hiểu được tại 2 dòng trống vừa chèn không có dữ liệu ở cột B, dòng trên em muốn điền tên "Cộng chi phí trực tiếp", dòng dưới em điền Thu nhập tên là "Thu nhập chịu thuế tính trước"
 
Upvote 0
Web KT

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

Back
Top Bottom