Nhờ mọi người hỗ trợ viết giúp Function

Liên hệ QC

dinhduy

Thành viên hoạt động
Tham gia
24/11/07
Bài viết
167
Được thích
76
Em chào mọi người, rất mong nhận được sự giúp đỡ. Em dùng công thức excel, nhưng với dữ liệu lớn thì File chạy rất chậm. Nhờ mọi người viết giúp mình Function cho sheet XUAT để thay thế hàm ah. Cụ thể như sau:
- Cột QUY ĐỔI: Căn cứ vào Mã hàng + Số lượng => chạy Quy đổi hệ thống
- Cột THÀNH TIỀN 1: Số lượng (hoặc Quy đổi) + Đơn giá => Tính Thành tiền
- Cột THÀNH TIỀN 2: Thành tiền 1 (hoặc Thành tiền 1 * VAT)
- Cột GIÁ TẤM: Căn cứ vào Mã hàng hóa * GIÁM M3.
Em có đính kèm File và có sẵn công thức excel ah (trích 1 phần số liệu để làm ví dụ). Em xin cám ơn !
 

File đính kèm

  • Function.xlsb
    317.1 KB · Đọc: 10
Em chào mọi người, rất mong nhận được sự giúp đỡ. Em dùng công thức excel, nhưng với dữ liệu lớn thì File chạy rất chậm. Nhờ mọi người viết giúp mình Function cho sheet XUAT để thay thế hàm ah. Cụ thể như sau:
- Cột QUY ĐỔI: Căn cứ vào Mã hàng + Số lượng => chạy Quy đổi hệ thống
- Cột THÀNH TIỀN 1: Số lượng (hoặc Quy đổi) + Đơn giá => Tính Thành tiền
- Cột THÀNH TIỀN 2: Thành tiền 1 (hoặc Thành tiền 1 * VAT)
- Cột GIÁ TẤM: Căn cứ vào Mã hàng hóa * GIÁM M3.
Em có đính kèm File và có sẵn công thức excel ah (trích 1 phần số liệu để làm ví dụ). Em xin cám ơn !
Chạy code
Mã:
Option Explicit

Sub XYZ()
  Dim sArr(), Res(), Res2(), Res3(), Res4(), Dic As Object
  Dim sRow&, i&, h#

  Set Dic = CreateObject("Scripting.Dictionary")
  With Sheets("MAHH")
    sArr = .Range("B3:E" & .Range("B" & Rows.Count).End(xlUp).Row).Value
  End With
  sRow = UBound(sArr)
  For i = 1 To sRow
    If sArr(i, 4) <> 0 Then Dic.Item(sArr(i, 1)) = sArr(i, 4)
  Next i
 
  With Sheets("XUAT")
    sArr = .Range("H3:S" & .Range("H" & Rows.Count).End(xlUp).Row).Value
  End With
  sRow = UBound(sArr)
  ReDim Res(1 To sRow, 1 To 1)
  Res2 = Res:     Res3 = Res:     Res4 = Res
  For i = 1 To sRow
    If Dic.exists(sArr(i, 1)) Then h = Dic.Item(sArr(i, 1)) Else h = 0
    If InStr(1, "m3,kg", sArr(i, 3)) > 0 Then Res(i, 1) = Round(h * sArr(i, 4), 4)
    If Res(i, 1) > 0 Then Res2(i, 1) = Round(Res(i, 1) * sArr(i, 6), 4)
    Res3(i, 1) = Round(Res2(i, 1) * (1 + sArr(i, 8)), 4)
    Res4(i, 1) = Round(h * sArr(i, 12), 4)
  Next i
  Application.ScreenUpdating = False
  With Sheets("XUAT")
    .Range("L3").Resize(sRow).Value = Res
    .Range("N3").Resize(sRow).Value = Res2
    .Range("P3").Resize(sRow).Value = Res3
    .Range("R3").Resize(sRow).Value = Res4
  End With
  Application.ScreenUpdating = True
End Sub
 
Upvote 0
Chạy code
Mã:
Option Explicit

Sub XYZ()
...
    If InStr(1, "m3,kg", sArr(i, 3)) > 0 Then Res(i, 1) = Round(h * sArr(i, 4), 4)
    If Res(i, 1) > 0 Then Res2(i, 1) = Round(Res(i, 1) * sArr(i, 6), 4)
    Res3(i, 1) = Round(Res2(i, 1) * (1 + sArr(i, 8)), 4)
    Res4(i, 1) = Round(h * sArr(i, 12), 4)
...
End Sub
Nếu không phải tính tiền với ngân hàng thì nên tránh hàm Round của VBA và dùng hàm Application.Round (của worksheet)
 
Upvote 0
Nếu không phải tính tiền với ngân hàng thì nên tránh hàm Round của VBA và dùng hàm Application.Round (của worksheet)
Ngoài việc hàm Round của VBA chỉ làm tròn tới hàng đơn vị, không cho làm tròn đến hàng chục, trăm ... không rỏ còn gì khác với Application.Round, nhờ bạn giải thích dùm, cám ơn bạn /-*+/
 
Upvote 0
Nếu chỉ cần làm tròn với tham số >=0 thì dùng hàm nào cũng được chứ bác?
Đây nè.

 
Upvote 0
Đây nè.

Lúc trước đã đọc nhưng quên mất:( :p
 
Upvote 0
Nếu chỉ cần làm tròn với tham số >=0 thì dùng hàm nào cũng được chứ bác?
Giống nhau (để ý trước số 5 là số lẻ):

1619419638952.png

Khác nhau (để ý trước số 5 là số chẵn):

1619419683251.png

Kết: trong cả hai lần trên, hàm VBA.Round làm tròn thành số chẵn (tức là 2),
 
Upvote 0
Việc dùng Function thay cho hàm chắc nó cũng lâu, mỗi lần mở file nó cũng chạy lại từ đầu.
Nếu đã dính tới việc phải dùng code thay cho công thức vì khối lượng lớn thì nên dùng Sub chạy luôn, ghi kết quả vào cells.
 
Upvote 0
Việc dùng Function thay cho hàm chắc nó cũng lâu, mỗi lần mở file nó cũng chạy lại từ đầu.
Nếu đã dính tới việc phải dùng code thay cho công thức vì khối lượng lớn thì nên dùng Sub chạy luôn, ghi kết quả vào cells.
Sự chọn lựa giữa Sub và Function không hẳn chỉ có thế.
Sub là "bút sa gà chết". Sub có thể sửa đổi dữ liệu.
Function chỉ trình bày, không sửa đổi.
 
Upvote 0
Sự chọn lựa giữa Sub và Function không hẳn chỉ có thế.
Sub là "bút sa gà chết". Sub có thể sửa đổi dữ liệu.
Function chỉ trình bày, không sửa đổi.
Chừ phải đặt gợi nhớ thế này thì sau mới khỏi quên: SUB "bút sa gà chết" là Sa vŨng Bùn @!>><
 
Upvote 0
Kết: trong cả hai lần trên, hàm VBA.Round làm tròn thành số chẵn (tức là 2),
thế thế dùng cái gì để thay thế á bác ( để được hàm round như thông thường sài trong toán học), ý cháu là không sài application.round hay workbookfunction, vì hai cái kia nó phải dựa vào môi trường excel, giả sử cần code vba trong word chẳng hạn.
 
Upvote 0
Chạy code
Mã:
Option Explicit

Sub XYZ()
  Dim sArr(), Res(), Res2(), Res3(), Res4(), Dic As Object
  Dim sRow&, i&, h#

  Set Dic = CreateObject("Scripting.Dictionary")
  With Sheets("MAHH")
    sArr = .Range("B3:E" & .Range("B" & Rows.Count).End(xlUp).Row).Value
  End With
  sRow = UBound(sArr)
  For i = 1 To sRow
    If sArr(i, 4) <> 0 Then Dic.Item(sArr(i, 1)) = sArr(i, 4)
  Next i

  With Sheets("XUAT")
    sArr = .Range("H3:S" & .Range("H" & Rows.Count).End(xlUp).Row).Value
  End With
  sRow = UBound(sArr)
  ReDim Res(1 To sRow, 1 To 1)
  Res2 = Res:     Res3 = Res:     Res4 = Res
  For i = 1 To sRow
    If Dic.exists(sArr(i, 1)) Then h = Dic.Item(sArr(i, 1)) Else h = 0
    If InStr(1, "m3,kg", sArr(i, 3)) > 0 Then Res(i, 1) = Round(h * sArr(i, 4), 4)
    If Res(i, 1) > 0 Then Res2(i, 1) = Round(Res(i, 1) * sArr(i, 6), 4)
    Res3(i, 1) = Round(Res2(i, 1) * (1 + sArr(i, 8)), 4)
    Res4(i, 1) = Round(h * sArr(i, 12), 4)
  Next i
  Application.ScreenUpdating = False
  With Sheets("XUAT")
    .Range("L3").Resize(sRow).Value = Res
    .Range("N3").Resize(sRow).Value = Res2
    .Range("P3").Resize(sRow).Value = Res3
    .Range("R3").Resize(sRow).Value = Res4
  End With
  Application.ScreenUpdating = True
End Sub
Em cám ơn anh nhiều ah!
Có thể là em nhầm ở đây, nhờ a sửa lại giúp em thay vì chạy Sub em muốn chạy trực tiếp trên SHEET XUAT luôn khi nhập (giống như hàm excel) để kiểm tra trực tiếp được từng phiếu xem có lệch không. Nhiều khi điều chỉnh lại xíu (do đơn vị m3 + VAT từng dòng). File này em theo dõi cho cả năm ah. (Sheet NHAP em sẽ làm tương tự Sheet XUAT - đã xóa). Rất mong được sự giúp đỡ của anh. Em cám ơn !

P/S: Cột GIÁ TẤM chỉ khi khách hàng yêu cầu tính ĐƠN GIÁ là TẤM thì em mới nhập số tiền ở cột GIÁ M3 vào đó sẽ ra được số tiền của 1 tấm rồi copy vào cột ĐƠN GIÁ ah.
 
Lần chỉnh sửa cuối:
Upvote 0
Em cám ơn anh nhiều ah!
Có thể là em nhầm ở đây, nhờ a sửa lại giúp em thay vì chạy Sub em muốn chạy trực tiếp trên SHEET XUAT luôn khi nhập (giống như hàm excel) để kiểm tra trực tiếp được từng phiếu xem có lệch không. Nhiều khi điều chỉnh lại xíu (do đơn vị m3 + VAT từng dòng). File này em theo dõi cho cả năm ah. (Sheet NHAP em sẽ làm tương tự Sheet XUAT - đã xóa). Rất mong được sự giúp đỡ của anh. Em cám ơn !

P/S: Cột GIÁ TẤM chỉ khi khách hàng yêu cầu tính ĐƠN GIÁ là TẤM thì em mới nhập số tiền ở cột GIÁ M3 vào đó sẽ ra được số tiền của 1 tấm rồi copy vào cột ĐƠN GIÁ ah.
Dùng công thức Excel tốt hơn code, chỉ cần tinh chỉnh lại công thức cho nhẹ hơn
 
Upvote 0
Web KT

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

Back
Top Bottom