Mình có 1 file theo dõi hàng nhập và xuất tại các sheets tương ứng.
Mình muốn xem nhanh số lượng từng mã hàng đã nhập theo thời gian (dùng code VBA) mà không biết cách làm thế nào.
Mong các bạn xem file đính kèm và giúp mình đoạn code nhé.
Tuy nhiên mình muốn sử dụng code vba (vì còn liên quan tới một số yếu tố khác). trong file mình up thì đã xử lý được phần hàng xuất. Còn phần hàng nhập thì mình chưa nắm rõ về mảng hai chiều nên chịu ngắc. Mong bạn xem và giúp mình đoạn code đó nhé.
P/s: Trong file mình up, ở sheet Nhapkhoxuong, cả phần mã hàng (dòng), và ngày (cột) vẫn còn sẽ tiếp tục nhập mở rộng.
Nhưng bạn xử lý nhầm phần xuất, mình đang gặp rắc rối ở phần nhập kho (sheets("nhapkhoxuong"). Cụ thể là khai báo, xử lý mảng động hai chiều khi Mã hàng (theo dòng) và ngày nhập kho (theo cột) đều có biến động hàng ngày
Bạn xem lại giúp mình userform trong file mình đã up nhé
Hic, thế thì hơi nan giải nhỉ. Vì phần này vẫn còn liên quan tới một số phần khác mình đã làm nên giờ bỏ thì lại phải làm lại hết.
Với phần nhập kho này thì mình đã làm theo kiểu đơn giản dùng 2 vòng lặp for thì xử lý được nhưng mà khi dữ liệu lớn lớn chút là chạy chậm quá. Nên mình định nghiên cứu dùng phương pháp mảng 2 chiều để cải thiện tốc độ. Nhưng mình gặp rắc rối phần khai báo mảng động quá.
Mình xin fát biểu vài nét về cách viết các câu lệnh trong macro của bạn như sau:
a). Khi đã chuye3n sang xài VBA thì tên trang tính như của bạn là hơi dài;
Bạn thấy mã chứng khoán của các đơn vị SX & KD trên sàn giao dịch không, chỉ có ba hay 4 từ thôi;
Tên "Nhapkhoxuong" theo mình là dài, nên chăng "NhapKX";
Nếu bắt buột f ải dài như vậy, sao không là "NhapKhoXuong" cho dễ đọc hay liếc thoáng qua là nhận ra ngay
Điều này cũng nên áp dụng cho các tên tham biến của bạn;
Sao không là "TuNgay" & "DenNgay", mà là "tungay" & "denngay"?
Tên cho macro cũng vậy; Nên là 'NapMa' thay vì 'Napma'
b). Nói thêm về tên tham biến & cách xài:
Ở Sub BaoCao bạn có 2 dòng lệnh như sau:
PHP:
Dim ArrXuat(), ArrNhap(), j As Long, i As Long, tungay As Date, denngay As Date, EndR As Long, EndRN As Long, EndCN As Long, hangxuat As String, hangnhap As String
Dim soluongxuat As Double, soluongnhap As Double
Nếu là mình thì mỉnh sẽ tách ra làm 3 dòng lệnh (không nhằm mục đích nào khác là dễ quản các tham biến mà thôi):
Mã:
Dim ArrXuat(), ArrNhap()
Dim J As Long, I As Long, TuNgay As Date, DenNgay As Date, EndR As Long, EndRN As Long, EndCN As Long, SLgXuat As Double, SLgNhap As Double
Dim HangXuat As String, HangNhap As String
b).1 Bạn nên khai báo tường minh, như
(trích các mệnh đề của bạn
Mã:
Dim ma
' . . . . .'
LastRow = ThisWorkbook.Worksheets("Nhapkhoxuong").Range("B" & ThisWorkbook.Worksheets("Nhapkhoxuong").Rows.Count).End(xlUp).Row
ma = ThisWorkbook.Worksheets("Nhapkhoxuong").Range("B4:B" & LastRow)
Rõ ràng ở đâu tham biến 'Ma' sẽ chứa mảng số liệu trong 1 vùng
Nếu là mình thì sẽ khai báo tường minh
PHP:
Dim Ma(), Sh As WorkSheet
Set Sh= ThisWorkbook.Worksheets("NhapKhoXuong")
LastRow = Sh.Range("B" & Sh.Rows.Count).End(xlUp).Row
Ma = Sh.Range("B4:B" & LastRow) .Value
Mình xin fát biểu vài nét về cách viết các câu lệnh trong macro của bạn như sau:
a). Khi đã chuye3n sang xài VBA thì tên trang tính như của bạn là hơi dài;
Bạn thấy mã chứng khoán của các đơn vị SX & KD trên sàn giao dịch không, chỉ có ba hay 4 từ thôi;
Tên "Nhapkhoxuong" theo mình là dài, nên chăng "NhapKX";
Nếu bắt buột f ải dài như vậy, sao không là "NhapKhoXuong" cho dễ đọc hay liếc thoáng qua là nhận ra ngay
Điều này cũng nên áp dụng cho các tên tham biến của bạn;
Sao không là "TuNgay" & "DenNgay", mà là "tungay" & "denngay"?
Tên cho macro cũng vậy; Nên là 'NapMa' thay vì 'Napma'
b). Nói thêm về tên tham biến & cách xài:
Ở Sub BaoCao bạn có 2 dòng lệnh như sau:
PHP:
Dim ArrXuat(), ArrNhap(), j As Long, i As Long, tungay As Date, denngay As Date, EndR As Long, EndRN As Long, EndCN As Long, hangxuat As String, hangnhap As String
Dim soluongxuat As Double, soluongnhap As Double
Nếu là mình thì mỉnh sẽ tách ra làm 3 dòng lệnh (không nhằm mục đích nào khác là dễ quản các tham biến mà thôi):
Mã:
Dim ArrXuat(), ArrNhap()
Dim J As Long, I As Long, TuNgay As Date, DenNgay As Date, EndR As Long, EndRN As Long, EndCN As Long, SLgXuat As Double, SLgNhap As Double
Dim HangXuat As String, HangNhap As String
b).1 Bạn nên khai báo tường minh, như
(trích các mệnh đề của bạn
Mã:
Dim ma
' . . . . .'
LastRow = ThisWorkbook.Worksheets("Nhapkhoxuong").Range("B" & ThisWorkbook.Worksheets("Nhapkhoxuong").Rows.Count).End(xlUp).Row
ma = ThisWorkbook.Worksheets("Nhapkhoxuong").Range("B4:B" & LastRow)
Rõ ràng ở đâu tham biến 'Ma' sẽ chứa mảng số liệu trong 1 vùng
Nếu là mình thì sẽ khai báo tường minh
PHP:
Dim Ma(), Sh As WorkSheet
Set Sh= ThisWorkbook.Worksheets("NhapKhoXuong")
LastRow = Sh.Range("B" & Sh.Rows.Count).End(xlUp).Row
Ma = Sh.Range("B4:B" & LastRow) .Value
Mình có 1 file theo dõi hàng nhập và xuất tại các sheets tương ứng.
Mình muốn xem nhanh số lượng từng mã hàng đã nhập theo thời gian (dùng code VBA) mà không biết cách làm thế nào.
Mong các bạn xem file đính kèm và giúp mình đoạn code nhé.
Cái này cũng đơn giản thôi, muốn thống kê được bên nhập kho thì phải viết 1 macro để chuẩn hóa lại dữ liệu thành 1 sheet nhập kho mới, sau đó dùng sheet nhập kho mới để xử lý.
Cái này cũng đơn giản thôi, muốn thống kê được bên nhập kho thì phải viết 1 macro để chuẩn hóa lại dữ liệu thành 1 sheet nhập kho mới, sau đó dùng sheet nhập kho mới để xử lý.
Theo hướng này cũng có lí à nha!
Nhưng theo mình, tác giả bài đăng nên có trang tính làm fụ trợ; Trên nới chứa danh mục hàng hóa;
Gồm các trường: [STT], [Mã HH], [Tên hàng], [ĐVT], [Lượng tồn theo đợt kiểm kê]
Chúng ta không thể tạo ra trang tính mà có nhiều dòng & cột trống hơ như vậy.
Với bảng 'DM HH' ta hoàn toàn khắc fục được chuyện này
Chuyện macro để chuyển từ trang tính 'Nhap. . . ' gì đó sang trang số liệu chuẩn cũng chả khó là bao:
Lấy 1 trang tính trắng
Tạo vòng lặp duyệt tại trang 'Nhap . .' những dòng có số lượng thì chép sang thành dòng mới ở trang mới này
Ví dụ:
PHP:
Sub TaoTrangNhapSanLuongHH()
Dim Rws As Long, J As Long, W As Long, Col As Byte, Cot As Integer
Dim Arr()
With Sheets("NhapKhoXuong").[b3]
Rws = .CurrentRegion.Rows.Count
Col = .End(xlToRight).Column
Arr() = .Offset(1).Resize(Rws, Col).Value
ReDim dArr(1 To Rws, 1 To 5)
End With
For Cot = 4 To Col
For J = 1 To UBound(Arr())
If Arr(J, Cot) <> 0 Then
W = W + 1: dArr(W, 1) = W
dArr(W, 2) = Cells(3, Cot).Value
dArr(W, 3) = Arr(J, 1): dArr(W, 4) = Arr(J, 2)
dArr(W, 5) = Arr(J, Cot)
End If
Next J
Next Cot
If W Then
Sheets("NhapKhoXuong").[cb4].Resize(W, 5).Value = dArr()
End If
End Sub
Đã khong chuẩn thì tất cả những cái liên quan đến nó đều lệch lạc. Làm lại hết là đúng rồi, còn gì phải luyến tiếc.
Đừng có nói với tôi là đồ án lớn nhé. Tôi là dân chuyên quản lý đồ án phần mềm. Đồ án lớn thì mọi liên liacj với CSDL đều ua giao diện. Nếu cơ cấu CSDL bị thay đổi thì chỉ cần thay đổi cái giao diện.
Mình có 1 file theo dõi hàng nhập và xuất tại các sheets tương ứng.
Mình muốn xem nhanh số lượng từng mã hàng đã nhập theo thời gian (dùng code VBA) mà không biết cách làm thế nào.
Mong các bạn xem file đính kèm và giúp mình đoạn code nhé.
Private Sub Baocao()
Dim Arr(), ArrNhap(), j As Long, i As Long, EndR As Long, FistC As Long, EndC As Long
Dim Tungay As Date, Denngay As Date, Hangxuat As String, Hangnhap As String
Dim SoluongXuat As Double, SoluongNhap As Double
On Error Resume Next
If Me.txtTungay.Value = "" Then
MsgBox ("Hay nhap ngay bat dau")
Exit Sub
Else
Tungay = Format(Me.txtTungay.Value, "dd/mm/yyyy")
End If
If Me.txtDenngay.Value = "" Then
MsgBox ("Hay nhap ngay ket thuc")
Exit Sub
Else
Denngay = Format(Me.txtDenngay.Value, "dd/mm/yyyy")
End If
If Me.cobHangxuat.Value <> "" Then Hangxuat = Me.cobHangxuat.Value
If Me.cobHangnhap.Value <> "" Then Hangnhap = Me.cobHangnhap.Value
With ThisWorkbook.Sheets("Xuatxuong")
EndR = .Range("A" & Rows.Count).End(xlUp).Row
Arr = .Range("A4:N" & EndR).Value
End With
For i = LBound(Arr) To UBound(Arr)
If Arr(i, 3) >= Tungay And Arr(i, 3) <= Denngay Then
If Arr(i, 9) = Hangxuat And IsNumeric(Arr(i, 12)) Then
SoluongXuat = SoluongXuat + Arr(i, 12)
End If
End If
Next i
With ThisWorkbook.Sheets("Nhapkhoxuong")
EndC = .Cells(3, 16000).End(xlToLeft).Column
EndR = .Range("B" & Rows.Count).End(xlUp).Row
Arr = .Range("B3", .Cells(EndR, EndC)).Value
End With
For j = 4 To UBound(Arr, 2)
If Arr(1, j) >= Tungay Then FistC = j: Exit For
Next j
If FistC = 0 Then GoTo Thoat
EndC = UBound(Arr, 2)
For n = j To UBound(Arr, 2)
If Arr(1, n) >= Denngay Then
If Arr(1, n) = Denngay Then EndC = n Else EndC = n - 1
Exit For
End If
Next n
For i = 2 To UBound(Arr)
If Arr(i, 1) = Hangnhap Then
For j = FistC To EndC
If Arr(i, j) <> Empty Then SoluongNhap = SoluongNhap + Arr(i, j)
Next j
End If
Next i
Thoat:
Me.lbHangxuat.Caption = SoluongXuat
Me.lbHangnhap.Caption = SoluongNhap
End Sub
Private Sub Baocao()
Dim Arr(), ArrNhap(), j As Long, i As Long, EndR As Long, FistC As Long, EndC As Long
Dim Tungay As Date, Denngay As Date, Hangxuat As String, Hangnhap As String
Dim SoluongXuat As Double, SoluongNhap As Double
On Error Resume Next
If Me.txtTungay.Value = "" Then
MsgBox ("Hay nhap ngay bat dau")
Exit Sub
Else
Tungay = Format(Me.txtTungay.Value, "dd/mm/yyyy")
End If
If Me.txtDenngay.Value = "" Then
MsgBox ("Hay nhap ngay ket thuc")
Exit Sub
Else
Denngay = Format(Me.txtDenngay.Value, "dd/mm/yyyy")
End If
If Me.cobHangxuat.Value <> "" Then Hangxuat = Me.cobHangxuat.Value
If Me.cobHangnhap.Value <> "" Then Hangnhap = Me.cobHangnhap.Value
With ThisWorkbook.Sheets("Xuatxuong")
EndR = .Range("A" & Rows.Count).End(xlUp).Row
Arr = .Range("A4:N" & EndR).Value
End With
For i = LBound(Arr) To UBound(Arr)
If Arr(i, 3) >= Tungay And Arr(i, 3) <= Denngay Then
If Arr(i, 9) = Hangxuat And IsNumeric(Arr(i, 12)) Then
SoluongXuat = SoluongXuat + Arr(i, 12)
End If
End If
Next i
With ThisWorkbook.Sheets("Nhapkhoxuong")
EndC = .Cells(3, 16000).End(xlToLeft).Column
EndR = .Range("B" & Rows.Count).End(xlUp).Row
Arr = .Range("B3", .Cells(EndR, EndC)).Value
End With
For j = 4 To UBound(Arr, 2)
If Arr(1, j) >= Tungay Then FistC = j: Exit For
Next j
If FistC = 0 Then GoTo Thoat
EndC = UBound(Arr, 2)
For n = j To UBound(Arr, 2)
If Arr(1, n) >= Denngay Then
If Arr(1, n) = Denngay Then EndC = n Else EndC = n - 1
Exit For
End If
Next n
For i = 2 To UBound(Arr)
If Arr(i, 1) = Hangnhap Then
For j = FistC To EndC
If Arr(i, j) <> Empty Then SoluongNhap = SoluongNhap + Arr(i, j)
Next j
End If
Next i
Thoat:
Me.lbHangxuat.Caption = SoluongXuat
Me.lbHangnhap.Caption = SoluongNhap
End Sub
Mình cũng vừa hì hục cả buổi xong. Nhờ bạn và mọi người xem giúp đoạn code của mình liệu có vấn đề gì không nhé
Mã:
With ThisWorkbook.Worksheets("Nhapkhoxuong")
Set sht = ThisWorkbook.Sheets("Nhapkhoxuong")
EndCN = .Cells(3, .Columns.Count).End(xlToLeft).Column
EndRN = .Range("B" & Rows.Count).End(xlUp).Row
ArrNhap = .Range("B3:B" & EndRN).Resize(, EndCN).Value
For j = 1 To UBound(ArrNhap, 1)
If ArrNhap(j, 1) = hangnhap Then
For k = 4 To UBound(ArrNhap, 2)
If ArrNhap(1, k) >= tungay And ArrNhap(1, k) <= denngay And IsNumeric(ArrNhap(j, k)) Then
soluongnhap = soluongnhap + ArrNhap(j, k)
End If
Next k
Exit For
End If
Next j
End With
Me.lbHangxuat.Caption = soluongxuat
Me.lbHangnhap.Caption = soluongnhap
End Sub
Theo hướng này cũng có lí à nha!
Nhưng theo mình, tác giả bài đăng nên có trang tính làm fụ trợ; Trên nới chứa danh mục hàng hóa;
Gồm các trường: [STT], [Mã HH], [Tên hàng], [ĐVT], [Lượng tồn theo đợt kiểm kê]
Chúng ta không thể tạo ra trang tính mà có nhiều dòng & cột trống hơ như vậy.
Với bảng 'DM HH' ta hoàn toàn khắc fục được chuyện này
Chuyện macro để chuyển từ trang tính 'Nhap. . . ' gì đó sang trang số liệu chuẩn cũng chả khó là bao:
Lấy 1 trang tính trắng
Tạo vòng lặp duyệt tại trang 'Nhap . .' những dòng có số lượng thì chép sang thành dòng mới ở trang mới này
Ví dụ:
PHP:
Sub TaoTrangNhapSanLuongHH()
Dim Rws As Long, J As Long, W As Long, Col As Byte, Cot As Integer
Dim Arr()
With Sheets("NhapKhoXuong").[b3]
Rws = .CurrentRegion.Rows.Count
Col = .End(xlToRight).Column
Arr() = .Offset(1).Resize(Rws, Col).Value
ReDim dArr(1 To Rws, 1 To 5)
End With
For Cot = 4 To Col
For J = 1 To UBound(Arr())
If Arr(J, Cot) <> 0 Then
W = W + 1: dArr(W, 1) = W
dArr(W, 2) = Cells(3, Cot).Value
dArr(W, 3) = Arr(J, 1): dArr(W, 4) = Arr(J, 2)
dArr(W, 5) = Arr(J, Cot)
End If
Next J
Next Cot
If W Then
Sheets("NhapKhoXuong").[cb4].Resize(W, 5).Value = dArr()
End If
End Sub
Cái này cũng đơn giản thôi, muốn thống kê được bên nhập kho thì phải viết 1 macro để chuẩn hóa lại dữ liệu thành 1 sheet nhập kho mới, sau đó dùng sheet nhập kho mới để xử lý.
Đã khong chuẩn thì tất cả những cái liên quan đến nó đều lệch lạc. Làm lại hết là đúng rồi, còn gì phải luyến tiếc.
Đừng có nói với tôi là đồ án lớn nhé. Tôi là dân chuyên quản lý đồ án phần mềm. Đồ án lớn thì mọi liên liacj với CSDL đều ua giao diện. Nếu cơ cấu CSDL bị thay đổi thì chỉ cần thay đổi cái giao diện.
Rất cảm ơn mọi người đã nhiệt tình góp ý. Căn bản mọi thứ mình đã hoàn làm xong theo nhu cầu của mình nên giờ lại phải làm lại thì ( đành phải cố tìm cách để xử lý vấn đề này.
Mình sẽ rút kinh nghiệm về việc "chuẩn hóa" CSDL trong các lần sau. Toàn tự mò cóp nhặt nên mệt thật.
Trong Form của chủ bài đăng có 2 nhãn để thể hiện 2 sản lượng nhập hay xuất hàng hóa.
trong cùng 1 thời kỳ (Ngày đàu & ngày cuối) cho 2 loại mặt hàng khác nhau.
Có thể xài các ListBox để hiện 2 danh sách hàng đã xuất hay nhập trong kỳ hay không?