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 đỡ./.
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 đỡ./.
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 đỡ./.
Đây là file của bạn
Chúc vui với công tác tính dự toán và trở thành một dự toán viên giỏi
Thân
P/S : sau khi cập nhật đầy đủ dữ liệu như trong Sheet Dutoanchitiet, hãy chạy Sub TinhTongTien trong Modull để cập nhật kết quả. Chú ý kết quả của Tổng tiền tính luôn phần Máy khác và Vật liệu khác
Đây là file của bạn
Chúc vui với công tác tính dự toán và trở thành một dự toán viên giỏi
Thân
P/S : sau khi cập nhật đầy đủ dữ liệu như trong Sheet Dutoanchitiet, hãy chạy Sub TinhTongTien trong Modull để cập nhật kết quả. Chú ý kết quả của Tổng tiền tính luôn phần Máy khác và Vật liệu khác
Cảm ơn anh rất nhiều,nhưng em chưa hiểu đoạn Code này có phải là đoạn thừa không ạh?
Sub Macro1()
'
' Macro1 Macro
' Macro recorded 01/07/2009 by XuanTruong
'
'
ActiveCell.FormulaR1C1 = "=SUM(R[1]C:R[4]C)"
Range("H15").Select
End Sub
Sub Macro2()
'
' Macro2 Macro
' Macro recorded 01/07/2009 by XuanTruong
'
'
Range("H11").Select
ActiveCell.FormulaR1C1 = "=SUM(R[1]C)"
Range("H12").Select
End Sub
Option Explicit
Sub SumFor()
Dim Rng As Range, sRng As Range, MyAdd As String
Dim Color_ As Byte, Rw As Long
Set Rng = Range([C65500].End(xlUp), [C7])
Set sRng = Rng.Find("")
If Not sRng Is Nothing Then
MyAdd = sRng.Address: Color_ = 35
Do
8 If Left(sRng.Offset(, -1), 1) = "M" Or Left(sRng.Offset(, -1), 1) = "N" Then
sRng.Offset(, 5).FormulaR1C1 = "=SUM(R[1]C:R[1]C)"
sRng.Offset(, 5).Interior.ColorIndex = IIf(Color_ = 35, 38, 35)
If Color_ = 38 Then Color_ = 35 Else Color_ = 38
12 Else
If sRng.Offset(2) = "" Then
Rw = 1: sRng.Offset(, 5).Font.ColorIndex = 3
Else
Rw = sRng.Offset(1).End(xlDown).Row - sRng.Row
End If
sRng.Offset(, 5).FormulaR1C1 = "=SUM(R[1]C:R[" & Rw & "]C)"
sRng.Offset(, 5).Interior.ColorIndex = 38
End If
Set sRng = Rng.FindNext(sRng)
Loop While Not sRng Is Nothing And sRng.Address <> MyAdd
End If
End Sub
Các anh làm thế nào mà viết code nhanh thế. Anh có thể bày cho em cách muốn sử dụng từ khóa như thế nào thì nhanh và hiệu quả nhất được không?. Em thường soạn viết Code trong Word rồi copy ra thôi. Trong khi nếu xử lý lỗi thì có khi hàng tiếng chẳng xong.
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.
Vì mới chập chững bước vào VBA nên kiến thức của em còn kém. Mong nhờ anh dịch hộ em ý nghĩa của dòng này : Range("H" & i).Formula = Replace("=SUM(" & _
Cells(i + 1, 8).Address & ":" & Cells(R1, 8).Address & ")", "$", "")
Các anh làm thế nào mà viết code nhanh thế. Anh có thể bày cho em cách muốn sử dụng từ khóa như thế nào thì nhanh và hiệu quả nhất được không?. Em thường soạn viết Code trong Word rồi copy ra thôi. Trong khi nếu xử lý lỗi thì có khi hàng tiếng chẳng xong.
Viết code thì người ta viết trực tiếp vào cửa sổ VBE chứ ai lại soạn thảo trên Word nhỉ? Lở có sai cú pháp còn biết đường mà lần... Soạn trong Word thì có mà... chết
From Sa_DQ:
Viết trong cửa sổ VBE có nhiều cái lợi:
(*) Phát hiện giúp ta gỏ sai chính tả:
Ví dụ ta gỏ các dòng lệnh
dim GPe as string
gpe = [A8].address
thì sau khi {ENTER} kết thúc dòng lệnh thứ nhứt, thằng VBE sẽ sửa lại là:
Dim GPe As String
(Nếu ta thiếu hay thừa kí tự trong chuỗi string thì nó không chuyển thành String cho ta;
Như vậy, chỉ cần 1 liếc mắt là phát hiện ngay lỗi không đáng có & khó phát hiện)
Ở dòng lệnh thứ 2, khi ta nhấp dấu '.', cái thằng VBE thông minh đáo để này sẽ cung cấp cho ta 1 danh sách đỗ xuống các lựa chọn; Vừa í cho ta cái nào, ta chọn cái đó.
Sau khi nhấn {ENTER} kết thú`c dòng lệnh thứ 2, VBE sẽ sửa lại thành:
GPe = [A8].Address
. . . . .
Vì mới chập chững bước vào VBA nên kiến thức của em còn kém. Mong nhờ anh dịch hộ em ý nghĩa của dòng này : Range("H" & i).Formula = Replace("=SUM(" & _
Cells(i + 1, 8).Address & ":" & Cells(R1, 8).Address & ")", "$", "")
Đoạn này dùng để điền công thức Sum() vào ô thứ i của cột H. Hai cái .Address địa chỉ ô đầu và ô cuối của vùng tính tổng. Replace để loại các ký tự "$" ra vì tôi muốn kết quả là địa chỉ tương đối.
Bạn nên viết trực tiếp trên cửa sổ VBE. Kích hoạt chức năng Auto List Members và Auto Quick Info (Thường thì tự kích hoạt) sẽ giúp bạn lập trình nhanh hơn. Không nhớ kỹ từ khóa vẫn có thể viết được.
Đoạn này dùng để điền công thức Sum() vào ô thứ i của cột H. Hai cái .Address địa chỉ ô đầu và ô cuối của vùng tính tổng. Replace để loại các ký tự "$" ra vì tôi muốn kết quả là địa chỉ tương đối.
Thông thường ít ai dùng hàm Replace để thay đổi địa chỉ tương đối, tuyệt đối... vì Address Property còn có các tham số ở bên trong cho phép bạn tùy chỉnh ---> Chẳng hạn để loại bỏ dấu $ người ta hay dùng .Address(0,0) Bạn có thể vào cửa sổ VBE, gõ chử Address, bôi đen nó rồi bấm F1 để biết thêm chi tiết
Thông thường ít ai dùng hàm Replace để thay đổi địa chỉ tương đối, tuyệt đối... vì Address Property còn có các tham số ở bên trong cho phép bạn tùy chỉnh ---> Chẳng hạn để loại bỏ dấu $ người ta hay dùng .Address(0,0) Bạn có thể vào cửa sổ VBE, gõ chử Address, bôi đen nó rồi bấm F1 để biết thêm chi tiết
IIF : Là lệnh IF được dùng trong VBA nó tương ứng với cấu trúc IF(Logic,True,False). Cú pháp là:
IIF(Logic,True,False).
Câu lệnh nào bảo rằng R1 = R1 trừ đi [nếu ô Cells(i,1) khác rỗng, True = 1, False = 0]
Vậy ha!
(*) Dòng lệnh thứ 7 Kết thúc điều kiện bắt đầu từ dòng thứ 2;
(*) Dòng lệnh 8 diễn dịch sang tiếng Việt như sau:
Nếu trị trong Cells(i, 1) khác rỗng thì gán R1-1 vô biến R1;
Ngược lại thì ta gán R1 vô R1 . . -> (có nghĩa là vũ như cẩn)
(a) Đó là HuuThang_BD nói về macro của HThang sẽ chạy nhanh hơn của AnhPhuong
Rõ ràng sẽ nhanh hơn, vì cùng 1 số records như nhau, AnhPhuong duyệt đến ba lần cho ba tiêu chí cần tổng hợp;
Của HuuThang_BD chỉ duyệt có 1 lần;
Nhưng chưa hết, Vòng lặp lại không nhanh hơn phương thức tìm kiếm (FIND()) trong vòng lặp Do. . Loop (tại bài #6)
Vì lúc đó, VBA chỉ tìm những ô trống trong cột đó mà thôi;
(a) Đó là HuuThang_BD nói về macro của HThang sẽ chạy nhanh hơn của AnhPhuong
Rõ ràng sẽ nhanh hơn, vì cùng 1 số records như nhau, AnhPhuong duyệt đến ba lần cho ba tiêu chí cần tổng hợp;
Của HuuThang_BD chỉ duyệt có 1 lần;
Nhưng chưa hết, Vòng lặp lại không nhanh hơn phương thức tìm kiếm (FIND()) trong vòng lặp Do. . Loop (tại bài #6)
Vì lúc đó, VBA chỉ tìm những ô trống trong cột đó mà thôi;
Bạn cứ hiểu thế này: Nếu C55 = "" thì R1 = 54, Nếu C54 = "" thì R1 = 53...
Cái này liên quan đến thuật toán. Tùy từng bài toán cụ thê mà ta có những thuật toán khác nhau sao cho hiệu quả nhất.
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
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
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 đượ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
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.
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.
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.
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.
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?
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?
Đế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]
Đế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
Đ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
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./.
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./.
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 ấysang 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 đó)
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 ấysang 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 đó)
Đế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"