Chương Trình Quản Lý Kho Vật Tư (phụ Tùng) (1 người xem)

  • Thread starter Thread starter vungoc
  • Ngày gửi Ngày gửi
Liên hệ QC

Người dùng đang xem chủ đề này

vungoc

Find Sexy Womans from your town for night
Tham gia
2/8/06
Bài viết
633
Được thích
2,604
Giới tính
Nam
Nghề nghiệp
Search
Gửi lên đây chia sẻ với các bạn CHƯƠNG TRÌNH QUẢN LÝ KHO VẬT TƯ (PHỤ TÙNG)

I- LỜI CẢM ƠN !

Trước hết tôi xin được trân trọng cảm ơn những người bạn đã rất rất nhiệt tình giúp đỡ tôi trong quá trình thực hiện chương trình này, xin gửi lời cảm ơn đến:
- Mr. Okebab (Mr. Hiếu)
- Anhphuong (Anh Phạm Xuân Trường)
- Anh ThuNghi
- SoiBien (Anh Quốc Anh)
Trong chương trình này có sử dụng một số đọan Code có trên diễn đàn GPE.


II- SỬ DỤNG CHƯƠNG TRÌNH:

1/- Setup chế độ cho Excel:
Mở Excel -> Chọn Tools -> Chọn Macros -> Chọn Security -> Chọn Medium

2/- Mở File QUẢN LÝ KHO PHỤ TÙNG (VẬT TƯ) chọn chế độ Enable Macros.

3/- Đọc kỹ hướng dẫn sử dụng, trước khi dùng.
(Nếu có có vấn đề vui lòng liên hệ: Mr. Vũ Ngọc - 0903744734)



III/- NHỮNG ĐIỀM CẦN HÒAN THIỆN:


Tuy đã rất cố gắng nhưng chắc chắn chương trình vẫn còn nhiều thiếu sót. Một lần nữa tôi rất mong tiếp tục nhận được sự trợ giúp của các bạn để hòan thiện cho những nội dung sau:

1- Thiết lập code sao cho khi mở File sẽ tự động bỏ qua bước chọn Enable macros và vào thẳng giao diện Menu chính của chương trình / hoặc người dùng chỉ có thể chọn được chế độ Enable Macros (Tránh trường hợp người dùng vô tình hoặc cố ý chọn chế độ Disable Macros).

2- Ở Form Giấy Đề Nghị:
- Khi ta nhập liệu xong một hóa đơn / chứng từ và kết thúc bằng nút CẬP NHẬP. Lúc này dữ liệu đã được ghi vào DATA, chúng ta có thể nhìn thấy dữ liệu trong List Data Tổng Hợp Các Giấy Đề Nghị (Ở Form Nhập Liệu Giấy Đề Nghị).

- Làm sao để khi ta gõ một Số Chứng Từ nào đó đã có trong List Data Tổng Hợp Các Giấy Đề Nghị vào trong Ô Textbox Số Chứng Từ tại Form Nhập Liệu Giấy Đề Nghị (hoặc ta chọn một dòng dữ liệu nào đó trong List Data Tổng Hợp Các Giấy Đề Nghị) thì dữ liệu sẽ hiện ngược lên List Ghi Tạm và các ô Textbox, Combobox tương ứng trên form này để chúng ta sửa được dữ liệu sau đó bấm Nút Sửa để cập nhật lại những dữ liệu đã được sửa vào Data GiayDeNghi.

3- Form DANH MỤC, tạo chức năng cho các nút: Thêm mới, Sửa, Xóa.

4- Và các vấn đề khác cần sửa đổi / cải tiến cho tốt hơn (theo ý mọi người).

Đây là phần mềm chia sẻ, chúng ta hãy cùng nhau mỗi người một tay, làm cho nó hòan thiện hơn để có một PM ứng dụng hòan chỉnh từ Excel góp vào thư viện của GPE.

Mong sớm nhận được sự đóng góp của tất cả các bạn cho chương trình này !

TRÂN TRỌNG CẢM ƠN TẤT CẢ CÁC BẠN VÀ GPE !
 

File đính kèm

Lần chỉnh sửa cuối:
Không thể nhấn nút thanks được mà ngoài lơi nói cảm ơn Vu Ngọc có ý tưởng , thực hiện mà còn phải nói lời cảm ơn của những người tiếp nhân đến tất cả những người đã góp phần hoàn thành chương trình quản lý này.

Cảm ơn thật nhiều.
 
vungoc đã viết:
I- LỜI CẢM ƠN !

Trước hết tôi xin được trân trọng cảm ơn những người bạn đã rất rất nhiệt tình giúp đỡ tôi trong quá trình thực hiện chương trình này, xin gửi lời cảm ơn đến:
- Mr. Okebab (Mr. Hiếu)
- Anhphuong (Anh Phạm Xuân Trường)
- Anh ThuNghi
- SoiBien (Anh Quốc Anh)
Trong chương trình này có sử dụng một số đọan Code có trên diễn đàn GPE.


II- SỬ DỤNG CHƯƠNG TRÌNH:

1/- Setup chế độ cho Excel:
Mở Excel -> Chọn Tools -> Chọn Macros -> Chọn Security -> Chọn Medium

2/- Mở File QUẢN LÝ KHO PHỤ TÙNG (VẬT TƯ) chọn chế độ Enable Macros.


III/- NHỮNG ĐIỀM CẦN HÒAN THIỆN:


Tuy đã rất cố gắng nhưng chắc chắn chương trình vẫn còn nhiều thiếu sót. Một lần nữa tôi rất mong tiếp tục nhận được sự trợ giúp của các bạn để hòan thiện cho những nội dung sau:

1- Thiết lập code sao cho khi mở File sẽ tự động hoặc người dùng chỉ có thể chọn được chế độ Enable Macros (Tránh trường hợp người dùng vô tình hoặc cố ý chọn chế độ Disable Macros).

2- Ở Form Giấy Đề Nghị:
- Khi ta nhập liệu xong một hóa đơn / chứng từ và kết thúc bằng nút CẬP NHẬP. Lúc này dữ liệu đã được ghi vào DATA, chúng ta có thể nhìn thấy dữ liệu trong List Data Tổng Hợp Các Giấy Đề Nghị.

- Làm sao để khi ta gõ một Số Chứng Từ nào đó đã có trong List Data Tổng Hợp Các Giấy Đề Nghị vào trong Ô Textbox Số Chứng Từ Click (hoặc ta chọn một dòng dữ liệu nào đó trong List Data Tổng Hợp Các Giấy Đề Nghị) thì dữ liệu sẽ hiện ngược lên List Ghi Tạm và các ô Textbox, Combobox tương ứng trên form này để chúng ta sửa được dữ liệu sau đó bấm Nút Sửa để cập nhật lại những dữ liệu đã được sửa vào Data.

3- Form DANH MỤC, tạo chức năng cho các nút: Thêm mới, Sửa, Xóa.

4- Và các vấn đề khác cần sửa đổi / cải tiến cho tốt hơn (theo ý mọi người).

TRÂN TRỌNG CẢM ƠN TẤT CẢ CÁC BẠN VÀ GPE !

Bác sửa lại chút xíu :
Tại Form Xuất :
Bỏ hẳn sub này đi, vì không cần thiết :
PHP:
Private Sub NMaHang_AfterUpdate()
    On Error Resume Next
    If CDbl(Me.NTon) <= 0 Then
        MsgBox "Ma hang nay Khong Xuat duoc vi Ton bang Khong", vbOKOnly, "Mr Vu Ngoc"
        Me.NMaHang = ""
    End If
End Sub

Thân!
 
PM này Vũ Ngọc phải nên có thưởng như Lã Bất Vi, đại ý, nếu ai sửa 1 chữ trong "Lã Thị Xuân Thu" sẽ được ngàn vàng (# 1 chai Ken).
Mình sẽ cố gắng kiếm bia thôi nhé.
 
ThuNghi đã viết:
PM này Vũ Ngọc phải nên có thưởng như Lã Bất Vi, đại ý, nếu ai sửa 1 chữ trong "Lã Thị Xuân Thu" sẽ được ngàn vàng (# 1 chai Ken).
Mình sẽ cố gắng kiếm bia thôi nhé.

Em hòan tòan đồng ý với bác.

Chúng ta hãy cố gắng cùng nhau hòan thiện PM này, xong tổ chức hòan công một phát cho nó hòanh tráng.

Hẹn gặp lại các bác với Ken & Tiên nhé !

Thân mến !

P/S: Chiều nay em có mặt ở SG, bác mà rảnh hú em nhé.
 
Lần chỉnh sửa cuối:
vungoc đã viết:
Gửi lên đây chia sẻ với các bạn CHƯƠNG TRÌNH QUẢN LÝ KHO VẬT TƯ (PHỤ TÙNG)

I- LỜI CẢM ƠN !

Trước hết tôi xin được trân trọng cảm ơn những người bạn đã rất rất nhiệt tình giúp đỡ tôi trong quá trình thực hiện chương trình này, xin gửi lời cảm ơn đến:
- Mr. Okebab (Mr. Hiếu)
- Anhphuong (Anh Phạm Xuân Trường)
- Anh ThuNghi
- SoiBien (Anh Quốc Anh)
Trong chương trình này có sử dụng một số đọan Code có trên diễn đàn GPE.


II- SỬ DỤNG CHƯƠNG TRÌNH:

1/- Setup chế độ cho Excel:
Mở Excel -> Chọn Tools -> Chọn Macros -> Chọn Security -> Chọn Medium

2/- Mở File QUẢN LÝ KHO PHỤ TÙNG (VẬT TƯ) chọn chế độ Enable Macros.

3/- Đọc kỹ hướng dẫn sử dụng, trước khi dùng.
(Nếu có có vấn đề vui lòng liên hệ: Mr. Vũ Ngọc - 0903744734)



III/- NHỮNG ĐIỀM CẦN HÒAN THIỆN:


Tuy đã rất cố gắng nhưng chắc chắn chương trình vẫn còn nhiều thiếu sót. Một lần nữa tôi rất mong tiếp tục nhận được sự trợ giúp của các bạn để hòan thiện cho những nội dung sau:

1- Thiết lập code sao cho khi mở File sẽ tự động bỏ qua bước chọn Enable macros và vào thẳng giao diện Menu chính của chương trình / hoặc người dùng chỉ có thể chọn được chế độ Enable Macros (Tránh trường hợp người dùng vô tình hoặc cố ý chọn chế độ Disable Macros).

2- Ở Form Giấy Đề Nghị:
- Khi ta nhập liệu xong một hóa đơn / chứng từ và kết thúc bằng nút CẬP NHẬP. Lúc này dữ liệu đã được ghi vào DATA, chúng ta có thể nhìn thấy dữ liệu trong List Data Tổng Hợp Các Giấy Đề Nghị (Ở Form Nhập Liệu Giấy Đề Nghị).

- Làm sao để khi ta gõ một Số Chứng Từ nào đó đã có trong List Data Tổng Hợp Các Giấy Đề Nghị vào trong Ô Textbox Số Chứng Từ tại Form Nhập Liệu Giấy Đề Nghị (hoặc ta chọn một dòng dữ liệu nào đó trong List Data Tổng Hợp Các Giấy Đề Nghị) thì dữ liệu sẽ hiện ngược lên List Ghi Tạm và các ô Textbox, Combobox tương ứng trên form này để chúng ta sửa được dữ liệu sau đó bấm Nút Sửa để cập nhật lại những dữ liệu đã được sửa vào Data GiayDeNghi.
- Tạo code cho nút xóa trong phần form Giấy đề nghị này.


3- Form DANH MỤC, tạo chức năng cho các nút: Thêm mới, Sửa, Xóa.

4- Và các vấn đề khác cần sửa đổi / cải tiến cho tốt hơn (theo ý mọi người).

Đây là phần mềm chia sẻ, chúng ta hãy cùng nhau mỗi người một tay, làm cho nó hòan thiện hơn để có một PM ứng dụng hòan chỉnh từ Excel góp vào thư viện của GPE.

Mong sớm nhận được sự đóng góp của tất cả các bạn cho chương trình này !

TRÂN TRỌNG CẢM ƠN TẤT CẢ CÁC BẠN VÀ GPE !

Hôm nay tôi post lên đây File đã sửa bổ sung một số vấn đề như:
1- In Label, In phiếu nhập, xuất kho.
2- Trong Form Giấy đề nghị, khi click chọn vào List Data Tổng Hợp các Giấy Đề Nghị thì danh mục hàng hóa đó đã hiển thị ngược lên trên để chúng ta có thể sửa và ghi lại.

Các phần cần hòan thiện như đã nêu trên xin mời các bạn tiếp tục tham gia !
Nếu sửa, vui lòng thực hiện trong file này.
 

File đính kèm

Lần chỉnh sửa cuối:
Sub THXNT()
Dim HC As Long
Dim i As Long
Dim Ma As Range

Application.Calculation = xlCalculationManual
HC = S109.Range("C65500").End(xlUp).Row

S109.Select
Range("EA9:P9").EntireColumn.Hidden = False
S109.Range("A9:O" & HC + 1).ClearContents
S109.Range("A10:O" & HC + 2).Select
Call NLine

HC = S101.Range("A65000").End(xlUp).Row

S109.Range("B9:C" & HC + 7).Value = S101.Range("A2:B" & HC).Value
S109.Range("D9:D" & HC + 7).Value = S101.Range("D2:D" & HC).Value
S109.Range("E9:F" & HC + 7).Value = S101.Range("F2:G" & HC).Value
S109.Range("O9:O" & HC + 7).Value = S101.Range("E2:E" & HC).Value
Range("G9:G" & HC + 7).FormulaR1C1 = "=SUMPRODUCT((DataNgay<R5C7)*((LEFT(DataPhieu,2)=""PN"")-(LEFT(DataPhieu,2)=""PX""))*(DataPTMa=RC[-5])*(DataPTSL))+RC[-2]"
Range("H9:H" & HC + 7).FormulaR1C1 = "=SUMPRODUCT((DataNgay<R5C7)*((LEFT(DataPhieu,2)=""PN"")-(LEFT(DataPhieu,2)=""PX""))*(DataPTMa=RC[-6])*(DataPTGT))+RC[-2]"
Range("I9:I" & HC + 7).FormulaR1C1 = "=SUMPRODUCT((DataNgay>=R5C7)*(DataNgay<=R5C9)*(LEFT(DataPhieu,2)=""PN"")*(DataPTMa=RC[-7])*(DataPTSL))"
Range("J9:J" & HC + 7).FormulaR1C1 = "=SUMPRODUCT((DataNgay>=R5C7)*(DataNgay<=R5C9)*(LEFT(DataPhieu,2)=""PN"")*(DataPTMa=RC[-8])*(DataPTGT))"
Range("K9:K" & HC + 7).FormulaR1C1 = "=SUMPRODUCT((DataNgay>=R5C7)*(DataNgay<=R5C9)*(LEFT(DataPhieu,2)=""PX"")*(DataPTMa=RC[-9])*(DataPTSL))"
Range("L9:L" & HC + 7).FormulaR1C1 = "=SUMPRODUCT((DataNgay>=R5C7)*(DataNgay<=R5C9)*(LEFT(DataPhieu,2)=""PX"")*(DataPTMa=RC[-10])*(DataPTGT))"
Range("M9:N" & HC + 7).FormulaR1C1 = "=RC[-6]+RC[-4]-RC[-2]"
Range("P9:P" & HC + 7).FormulaR1C1 = "=IF(SUM(RC[-9]:RC[-2])>0,1,"""")"

With S109.Range("B9:P" & HC + 7)
.Calculate
.Value = .Value
.Sort Key1:=Range("P9"), Order1:=xlAscending, Key2:=Range( _
"B9"), Order2:=xlAscending, Header:=xlNo, OrderCustom:=1, MatchCase _
:=False, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal, _
DataOption2:=xlSortNormal
End With

i = S109.Range("P65000").End(xlUp).Row
If i < 10 Then i = 10
S109.Range("A" & i + 1 & ":P" & HC + 7).ClearContents
S109.Range("P1:P5000").ClearContents

With Range("A9:A" & i)
.FormulaR1C1 = "=ROW()-8"
.Calculate
.Value = .Value
End With
With Range("E" & i + 2 & ":N" & i + 2)
.FormulaR1C1 = "=SUM(R9C:R[-1]C)"
.Calculate
.Value = .Value
End With
Range("C" & i + 2) = "TONG CONG"
Range("E9:F9").EntireColumn.Hidden = True
S109.Range("A10:O" & i + 1).Select
Call YLine
S109.Range("A" & i + 2 & ":O" & i + 2).Select
Call YLineTC
Range("D5").Select
End Sub
Sao tôi thử bỏ bớt .Calculate mà vẫn chạy ào ào, vậy có dư không.
Còn .FormulaR1C1 hình như cũng không cần.
Range("P9:P" & HC + 7).FormulaR1C1 = "=IF(SUM(RC[-9]:RC[-2])>0,1,"""")"
Thay bằng (bỏ .FormulaR1C1)
Range("P9:P" & HC + 7) = "=IF(SUM(RC[-9]:RC[-2])>0,1,"""")"
Tạo sao không làm thẳng vào cột A mà phải cột B, với lại chỉ cần tồn đầu kỳ + nhập trong kỳ >0 là lấy rồi không cần sum hết.
Tôi làm thử code sau, Vũ Ngọc xem thử. Vẫn theo thuật tóan cũ.
PHP:
Sub THXNT()
    Dim HC As Long
    Dim i As Long, j As Long
    Application.Calculation = xlCalculationManual
    HC = S109.Range("C65500").End(xlUp).Row
    S109.Select
    Range("EA9:P9").EntireColumn.Hidden = False
    S109.Range("A9:O" & HC + 1).ClearContents
    S109.Range("A10:O" & HC + 2).Select
    Call NLine
    HC = S101.Range("A65000").End(xlUp).Row
    S109.Range("B9:C" & HC + 7).Value = S101.Range("A2:B" & HC).Value
    S109.Range("D9:D" & HC + 7).Value = S101.Range("D2:D" & HC).Value
    S109.Range("E9:F" & HC + 7).Value = S101.Range("F2:G" & HC).Value
    S109.Range("O9:O" & HC + 7).Value = S101.Range("E2:E" & HC).Value
    Range("G9:G" & HC + 7) = "=SUMPRODUCT((DataNgay<R5C7)*((LEFT(DataPhieu,2)=""PN"")-(LEFT(DataPhieu,2)=""PX""))*(DataPTMa=RC[-5])*(DataPTSL))+RC[-2]"
    Range("H9:H" & HC + 7) = "=SUMPRODUCT((DataNgay<R5C7)*((LEFT(DataPhieu,2)=""PN"")-(LEFT(DataPhieu,2)=""PX""))*(DataPTMa=RC[-6])*(DataPTGT))+RC[-2]"
    Range("I9:I" & HC + 7) = "=SUMPRODUCT((DataNgay>=R5C7)*(DataNgay<=R5C9)*(LEFT(DataPhieu,2)=""PN"")*(DataPTMa=RC[-7])*(DataPTSL))"
    Range("J9:J" & HC + 7) = "=SUMPRODUCT((DataNgay>=R5C7)*(DataNgay<=R5C9)*(LEFT(DataPhieu,2)=""PN"")*(DataPTMa=RC[-8])*(DataPTGT))"
    Range("K9:K" & HC + 7) = "=SUMPRODUCT((DataNgay>=R5C7)*(DataNgay<=R5C9)*(LEFT(DataPhieu,2)=""PX"")*(DataPTMa=RC[-9])*(DataPTSL))"
    Range("L9:L" & HC + 7) = "=SUMPRODUCT((DataNgay>=R5C7)*(DataNgay<=R5C9)*(LEFT(DataPhieu,2)=""PX"")*(DataPTMa=RC[-10])*(DataPTGT))"
    Range("M9:N" & HC + 7) = "=RC[-6]+RC[-4]-RC[-2]"
    Range("A9:A" & HC + 7) = "=IF(SUM(RC7:RC9)>0,1,"""")"
        
    With S109.Range("a9:N" & HC + 7)
        .Value = .Value
        .Sort Key1:=Range("A9"), Order1:=xlAscending, Key2:=Range( _
            "B9"), Order2:=xlAscending, Header:=xlNo, OrderCustom:=1, MatchCase _
            :=False, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal, _
            DataOption2:=xlSortNormal
      
    End With

    i = S109.Range("A65000").End(xlUp).Row
    If i < 10 Then i = 10
    S109.Range("A" & i + 1 & ":P" & HC + 7).ClearContents
       
    With Range("A9:A" & i)
        .FormulaR1C1 = "=ROW()-8"
        .Value = .Value
    End With
    With Range("E" & i + 2 & ":N" & i + 2)
        .FormulaR1C1 = "=SUM(R9C:R[-1]C)"
        .Value = .Value
    End With
    
    Range("C" & i + 2) = "T" & ChrW$(7893) & "ng " & "c" & ChrW$(7897) & "ng"
    Range("E9:F9").EntireColumn.Hidden = True
    S109.Range("A10:O" & i + 1).Select
    Call YLine
    S109.Range("A" & i + 2 & ":O" & i + 2).Select
    Call YLineTC
    Range("D5").Select
End Sub
Nhờ các bạn nghiên cứu hộ.
 
Lần chỉnh sửa cuối:
ThuNghi đã viết:
Sao tôi thử bỏ bớt .Calculate mà vẫn chạy ào ào, vậy có dư không.
Còn .FormulaR1C1 hình như cũng không cần.
Range("P9:P" & HC + 7).FormulaR1C1 = "=IF(SUM(RC[-9]:RC[-2])>0,1,"""")"
Thay bằng (bỏ .FormulaR1C1)
Range("P9:P" & HC + 7) = "=IF(SUM(RC[-9]:RC[-2])>0,1,"""")"
Tạo sao không làm thẳng vào cột A mà phải cột B, với lại chỉ cần tồn đầu kỳ + nhập trong kỳ >0 là lấy rồi không cần sum hết.
Tôi làm thử code sau, Vũ Ngọc xem thử. Vẫn theo thuật tóan cũ.

[/php] Nhờ các bạn nghiên cứu hộ.

Việc có thêm .Caculate là một thói quen khi lập trình (giống như khi khai báo Dim).
Ngay khi bắt đầu ta đã cho Application.Calculation = xlCalculationManual
Vì vậy với bất cứ việc tính toán nào trên Sheet (không kể tính trên VBA) thì ta nên sử dụng .Caculate để đảm bảo rằng việc tính toán này xảy ra.
With S109.Range("B9:P" & HC + 7)
.Calculate

Cái này bác không được bỏ, vì nếu bỏ thì vùng này sẽ không được tính toán -->> Kết quả sai.

Việc cho .FormualaR1C1 chẳng qua là để tính giá trị của nó thôi, sợ rằng khi Sort mà có công thức thì sẽ chậm hơn là không có công thức (???), vì vậy mới có nó.

Còn theo đề nghị thì cứ Mã hàng nào có tồn đầu kỳ, hoặc có phát sinh hoặc có tồn cuối kỳ thì sẽ được tính toán, còn không thì xóa hết.

Tạo sao không làm thẳng vào cột A mà phải cột B,
Cái này không hiểu lắm ??? Cột A để đánh số TT, cột B là mã hàng . Ý bác là bỏ STT đi à ??? cái này thì đơn giản thôi mà, ai thích thì có, không thích thì bỏ, có ảnh hưởng gì đâu.


Thân!
 
313132132132132131
 
Lần chỉnh sửa cuối:
1. Đó là việc các bạn ko bắt lỗi nên đại đa số xảy ra Runtime error, rồi nhảy ngay vào màn hình IDE của VBA.
2. Khi nhìn vào code (lúc bị lỗi thì nhảy ngay vào code - VBA's IDE), thấy các bạn viết quá cụ thể tới từng cell (A5, B5 gì đó), range, sheet, v.v... mà trong lập trình ít khi người ta viết cụ thể như vậy (Sao các bạn ko đặt tên vùng, v.v... đi, ko nên viết cụ thể như mấy dòng code ở topic trên, hay là trong Excel phải viết tường minh cho cell kiểu A4j....nhỉ?). Viết như vậy rất dễ bị lỗi. Theo mình nghĩ, viết trong VB đã tường minh rồi mà rất dễ xảy ra lỗi nếu ko biết viết, trong Excel's VBA còn khó hơn vì các cells, ranges, sheets,... thường đụng đến những thứ rất cụ thể. Mình rất hay viết kiểm tra trước khi thực hiện như: If cmdSave.Enable Then cmdSave.SetFocus chứ ko bao giờ mình viết thẳng cmdSave.SetFocus ngay. Như thế hạn chế được lỗi rất nhiều.
3. Có rất nhiều thao tác rất bình thường (save, thoát, v.v...) chạy chả hiểu sao ... lâu thế và 90% các thao tác như vậy dẫn đến treo Excel (hình như nó ghi vào file Excel). Tôi thường thao tác vài cái thì ... treo excel (hay là tôi chưa quen làm việc với Excel nhỉ???). Lần nào Excel của tôi mở các chương trình có VBA là y như rằng Excel của tôi cứ lăn quay ra chết.
Vâng, vì vậy GPE này rất cần những người . . . như bác!!!!!!!!

Ko rõ ý này có đụng chạm gì đến Excel ko nhé, nếu có gì ko phải thì mình xin lỗi trước, đó là việc mình thấy tại sao các bạn đang viết chương trình dưới dạng nhập liệu bằng Form thì tại sao lại viết trên Excel mà lại ko viết trên Access. Access cho phép tổ chức CSDL có quan hệ 1 chút, làm form và báo cáo cũng nhanh. Khi lưu record vào CSDL thì nhanh chứ ko phải save file Excel vào harddisk (cái này thì mình thấy tệ nhất khi làm trên Excel vì save file lâu kinh khủng). Mà rất rõ ràng trong bộ MS Office thì MS Access là công cụ để làm các chương trình quản lý vừa và nhỏ là rất phù hợp (còn Excel là bảng tính dạng ... Sheets). Nếu những lời này ko phù hợp thì mình sorry trước.
Cái này thì . . . vô cùng đúng . . nhưng lại rất nhiều người không theo kịp. Bởi làm ở Excel thì chẳng cần hiểu cấu trúc CSDL là gì cũng có thể làm được một cái gì đấy hay hay. Tuy nhiên nếu dùng Access mà không có những cái nền tảng đó thì coi như . . . thua.
Đây chính là một trong những lý do mà mọi người mất rất nhiều công sức với excel mà vẫn cứ làm trong khi đó để giải quyết vấn đề đó thì đối với Access (mới chỉ là Access thôi) coi như trò trẻ con.
Vì vậy Excell vẫn được ưa chuộng


P/S: Vừa chạy lại, trong màn hình xuất hàng, tại sao bấm nút cập nhật thì lại ... Printing??? (khó hiểu quá trời). Mình vội cancel printing thì chả thấy Excel đâu nữa :(
Cái này thì làm sao mà bác hiểu ngay được. Em là người trợ giúp mà còn lơ mơ nữa là. Vì đây là vấn đề đặc thù, đáng lý VuNgoc đưa lên File này sẽ phải nêu ra bài toán của File này như thế nào (Giải quyết vấn đề gì ??? tại sao??? . . . ). Nhưng chắc do thời gian không nhiều nên chưa viết

Nhân đây cũng nhắc nhở bác là nên cài một phần mềm in ảo để xem quản lý việc in ấn cũng như xem rằng cái mình in ra thực tế nó như thế nào (không phải lúc nào View cũng đúng đâu, đặc biệt là Excel)

Thân!
 
Lần chỉnh sửa cuối:
32132132132132132131
 
Lần chỉnh sửa cuối:
smbsolutions đã viết:
Nhưng thấy sau khi bấm "Cập nhật" mà nó Printing thì theo thói quen là "giật mình" và ... Esc vội :D :D

Chẳng qua là đặt tên hơi . . . Đáng lý phải là Lưu (hoặc Save). Chắc là bác VuNgoc muốn nói đến cái việc cập nhật dữ liệu từ Form vào trong Sheet Data. (Cái này phải nói là Lưu mới đúng)

Còn việc in là do khi Lưu chứng từ lại thì phải in ra chứng từ đó (mặc định), còn nếu không thích thì bỏ chọn (trên Form)

Còn cái việc làm cái List như bác nói quả thực là rất hay, nếu bác hoặc ai đó bỏ chút thời gian để làm mấy cái VD hoặc mấy cái bài về vấn đề này thì tốt quá. Em cũng thắc mắc rất nhiều về nó, làm sao để nhanh hơn nữa. Tuy nhiên cố gắng dùng ngôn ngữ và VD bình dân thì mới mong tụi em tiếp thu được. (kể cũng lạ, muốn học tiến sĩ mà cứ đòi phải được nghe giảng và đọc tài liệu = Tiếng Việt+-+-+-++-+-+-+)
Riêng khoản này thì bác phải thông cảm, tụi em không phải dân chuyên, chỉ lấy đây là niềm vui thôi nên cao quá là . . . đuối.

Thân!
 
Chữ màu đỏ là của Mr. Vũ Ngọc:

smbsolutions đã viết:
Tôi cũng thử sơ bộ file Excel này. Đây cũng là 1 file khá công phu, chứng tỏ tác giả cũng rất tập chung vào sản phẩm.

Tôi cũng định chạy thử để report lên cho các bạn nhưng... lại một lần nữa gặp phải vấn đề mà lần nào tôi chạy các file Excel cũng bị (chưa kịp làm gì).

1. Đó là việc các bạn ko bắt lỗi nên đại đa số xảy ra Runtime error, rồi nhảy ngay vào màn hình IDE của VBA (Sao mình test thử nhiều lần mà chưa bị trường hợp này - có ai bị giống smb... không cho mình biết luôn để tìm cách khắc phục).

2. Khi nhìn vào code (lúc bị lỗi thì nhảy ngay vào code - VBA's IDE), thấy các bạn viết quá cụ thể tới từng cell (A5, B5 gì đó), range, sheet, v.v... mà trong lập trình ít khi người ta viết cụ thể như vậy (Sao các bạn ko đặt tên vùng, v.v... đi, ko nên viết cụ thể như mấy dòng code ở topic trên, hay là trong Excel phải viết tường minh cho cell kiểu A4j....nhỉ?). (Trên excel phải vậy thôi) Viết như vậy rất dễ bị lỗi. Theo mình nghĩ, viết trong VB đã tường minh rồi mà rất dễ xảy ra lỗi nếu ko biết viết, trong Excel's VBA còn khó hơn vì các cells, ranges, sheets,... thường đụng đến những thứ rất cụ thể. Mình rất hay viết kiểm tra trước khi thực hiện như: If cmdSave.Enable Then cmdSave.SetFocus chứ ko bao giờ mình viết thẳng cmdSave.SetFocus ngay. Như thế hạn chế được lỗi rất nhiều.

3. Có rất nhiều thao tác rất bình thường (save, thoát, v.v...) (2 nút này đồng thời là nút SAVE - cho nên hơi lâu) chạy chả hiểu sao ... lâu thế và 90% các thao tác như vậy dẫn đến treo Excel (hình như nó ghi vào file Excel). Tôi thường thao tác vài cái thì ... treo excel (hay là tôi chưa quen làm việc với Excel nhỉ???). Lần nào Excel của tôi mở các chương trình có VBA là y như rằng Excel của tôi cứ lăn quay ra chết (Đúng là bác chưa quen với sử dụng ex rồi)

Rất tiếc là khi đã có quá nhiều runtime xảy ra thì mình lại ko thể tiếp tục chạy chương trình để test được nữa

Ko rõ ý này có đụng chạm gì đến Excel ko nhé, nếu có gì ko phải thì mình xin lỗi trước, đó là việc mình thấy tại sao các bạn đang viết chương trình dưới dạng nhập liệu bằng Form thì tại sao lại viết trên Excel mà lại ko viết trên Access. Access cho phép tổ chức CSDL có quan hệ 1 chút, làm form và báo cáo cũng nhanh. Khi lưu record vào CSDL thì nhanh chứ ko phải save file Excel vào harddisk (cái này thì mình thấy tệ nhất khi làm trên Excel vì save file lâu kinh khủng). Mà rất rõ ràng trong bộ MS Office thì MS Access là công cụ để làm các chương trình quản lý vừa và nhỏ là rất phù hợp (còn Excel là bảng tính dạng ... Sheets). Nếu những lời này ko phù hợp thì mình sorry trước.
(Rất muốn làm bằng Accsess nhưng tớ chả hiểu gì về nó cả nên phải làm bằng excel thôi !)


P/S: Vừa chạy lại, trong màn hình xuất hàng, tại sao bấm nút cập nhật thì lại ... Printing??? (khó hiểu quá trời). (Bấm cập nhật đồng nghĩa với việc làm xong nghĩa vụ ghi một chứng từ / hóa đơn, lúc ấy phải in luôn phiếu nhập hoặc xuất kho - đây là yêu cầu công việc của mình) Mình vội cancel printing thì chả thấy Excel đâu nữa :(. Lại phải vào Kill process)

Chạy lại quả nữa: Vào danh mục, tự nhiên thấy danh mục đã được list ra mà ko thấy cái option nào được check (tức là ko hiểu danh mục nào là hiện thời nữa). Sau đó, mình thử bấm vào "1-Phụ tùng" thì... mãi mới thấy danh mục được list lại (mình cứ tưởng...lại treo máy) - (Vấn đề này mình sẽ tiếp tục ghi nhận để cải tiến)

Nếu mà các bạn Add-Item lên ListBox thì thực sự ko được rồi các bạn ạ. Vì:

Thứ nhất, không có ai dùng Listbox (kể cả multi-listbox của FM20.DLL) để list những dữ liệu lớn (Vấn đề này mình lại phải nhờ các cao thủ trợ giúp rồi - có ai có pp khác giúp mình với nhé)

Thứ 2, Add item chỉ nên làm việc với lượng record là cực kỳ limited (danh sách đơn vị, phòng ban, kho hàng... thì OK chứ danh sách hàng hóa, vật tư, khách hàng,... thì ko nên). Bạn nên nghiên cứu về Grid (tỷ như cái lìu tìu nhất là MS Flexgrid có ngay trong Windows chẳng hạn) hoặc dùng ngay Sheet của Excel để list danh mục ra cũng được (như cái danh mục hay sổ nhật ký của A-Excel của Tuân ấy). Sheet của Excel có method để có thể query dữ liệu lên sheet thông qua ODBC APIs (cái này cũng cũ lắm rồi).

Thứ 3, khi có 1 long process thì nên thông báo cho người dùng chờ đợi (màn hình thông báo hoặc ít nhất có cái đồng hồ cát). Chứ bao lần mình tưởng ... treo máy Vấn đề này mình đã nghĩ tới, và cũng rất muốn như thế nhưng chưa làm được, nhờ các cao thủ giúp mình mục này đi
.
-

Cảm ơn ý kiến đóng góp của bạn.
Tiếp tục mong nhận được sự trợ giúp để khắc phục những điểm đã nêu trên.

Thân ái !
 
Lần chỉnh sửa cuối:
121314343432432432
 
Lần chỉnh sửa cuối:
smbsolutions đã viết:
Trên diễn đàn có ví dụ làm việc với dữ liệu Excel, đẩy lên MS FlexGrid sử dụng ADO rồi đấy. Chỉ viết thêm tý tẹo nữa là OK. Mỗi tội viết ... VB. Nhưng mình nghĩ cũng thế cả thôi. Cách làm việc với dữ liệu thì tạm thời nên sử dụng ADO đi (bác Duyệt làm món này nhiều rồi mà)

Bác Duyệt ơi, chung với em một tay đi nào !!!
 
30918382130921831
 
Lần chỉnh sửa cuối:
smbsolutions đã viết:
Trên diễn đàn có ví dụ làm việc với dữ liệu Excel, đẩy lên MS FlexGrid sử dụng ADO rồi đấy. Chỉ viết thêm tý tẹo nữa là OK. Mỗi tội viết ... VB. Nhưng mình nghĩ cũng thế cả thôi. Cách làm việc với dữ liệu thì tạm thời nên sử dụng ADO đi (bác Duyệt làm món này nhiều rồi mà)
Vâng, Bác Duyệt làm nhiều rồi, nhưng bác ấy cứ như là Yang Can Cook ấy.
Làm món thì cực ngon (em khỏi phải quảng cáo), luôn miệng nói là : Yang làm được, các bạn cũng làm được.
Híc híc, em làm theo bác ấy mà được thì em . . chết liền. Cũng bởi bì em . . ngu quá đấy mà.+-+-+-++-+-+-+
Lấy File của bác ấy, lắp ghép vào thì chạy Ok, tuy nhiên để hiểu được nó để khi áp dụng từng phần vào cái của mình thì lại . . . chít em.

Thôi, đành chạy ra cửa hàng ăn của Yang mua mấy phần về ăn thôi, còn Yang làm thế nào để ra các món ăn đó thì . . . hồi sau sẽ rõ.

(Cũng giống như bây giờ em hướng dẫn cho các bạn mới chập chững đi vào Excel làm 1 Form, làm 1 UF vậy)

Híc híc híc!!!

Thân!

P/S : Em nói thế các bác đừng giận em và cũng đừng nản lòng. Người ta thường nói : Danh sư xuất cao đồ.
Cũng chỉ tại tụi em không được thông minh lắm, lại không chuyên tâm nên mới đòi hỏi "bình dân học vụ" như vậy. Nếu thấy không hợp thì bỏ qua mấy bài kiểu này của em. Cảm ơn các bác.
 
Lần chỉnh sửa cuối:
Mình là dân "Mò", vì chẳng học tí ti nào về IT cũng như lập trình, bởi vậy phải lấy cái cần cù rồi lại "mò tiếp". Từ khi biết GPE cứ DownLoad file rồi xem, rồi mò mẫm, rồi làm ứng dụng cho công việc cụ thể (Những việc này thấy mấy em nhân viên trong công ty cứ phải làm thủ công mất thời gian mà kém hiệu quả) vậy là tính trách nhiệm lại phải trỗi dậy, quyết làm để thay đổi cách làm việc cho hiệu quả hơn. Tuy là mình mệt (vì đêm nào cũng mọ mẫm suốt đến khuya lắc - vợ con buồn quá trời vì không có thời gian để ... tâm sự) nhưng giúp mấy ẻm khỏe hơn để vui cười ... cho đời thêm tươi !!!

Tuy rất cố gắng nhưng mò mãi cũng phải tắc, đành phải chạy tới các bác Okebab, bác anhphuong, ThuNghi, ... phải nói là mọi người đều rất nhiệt tình giúp đỡ (có hôm bác MrOkebab phải mất cả ngày trời với mình, mà vẫn vui vẻ).

Được các bác chỉ bảo ngọn ngành thì là điều quý lắm rồi / cảm ơn nhiều !

Chúc mọi người luôn vui vẻ !
 
Lần chỉnh sửa cuối:
Lần nào Excel của tôi mở các chương trình có VBA là y như rằng Excel của tôi cứ lăn quay ra chết (Đúng là bác chưa quen với sử dụng ex rồi)

Nói là ko biết sử dụng là nói vui vậy thôi chứ tôi ko ngớ ngẩn đến mức ko làm Excel mà ko hiểu cách test ứng dụng đâu (tớ coding quen nên biết đụng vào đâu thì biết là xảy ra lỗi runtime). Phần mềm nào tôi test mà chẳng ra lỗi kiểu đó (chứ đừng nói đến Excel). Misa nổi tiếng là làm theo quy trình CMM level mấy gì đó mà khi tớ xóa hết dữ liệu đi thì lỗi cũng xảy ra. (Lập trình là bao giờ cũng có 1 kiểu kiểm tra (trong rất nhiều kiểu test) khi ko có dữ liệu và khi có cực nhiều dữ liệu). Đối với tớ, ở nghề lập trình thì tính cẩn thận được đặt lên hàng số 1.

VungNgoc cứ thử mấy cái combo box trong mục báo cáo, chọn xong rồi xóa đi (khi listindex = -1 mới gây ra đầy lỗi). Cái này dân lập trình biết là rất hay lỗi nên chỉ cần sờ đến là biết ngay lỗi sẽ xảy ra ở đâu mà. :)
 
smbsolutions đã viết:
Nói là ko biết sử dụng là nói vui vậy thôi chứ tôi ko ngớ ngẩn đến mức ko làm Excel mà ko hiểu cách test ứng dụng đâu (tớ coding quen nên biết đụng vào đâu thì biết là xảy ra lỗi runtime). Phần mềm nào tôi test mà chẳng ra lỗi kiểu đó (chứ đừng nói đến Excel). Misa nổi tiếng là làm theo quy trình CMM level mấy gì đó mà khi tớ xóa hết dữ liệu đi thì lỗi cũng xảy ra. (Lập trình là bao giờ cũng có 1 kiểu kiểm tra (trong rất nhiều kiểu test) khi ko có dữ liệu và khi có cực nhiều dữ liệu). Đối với tớ, ở nghề lập trình thì tính cẩn thận được đặt lên hàng số 1.

VungNgoc cứ thử mấy cái combo box trong mục báo cáo, chọn xong rồi xóa đi (khi listindex = -1 mới gây ra đầy lỗi). Cái này dân lập trình biết là rất hay lỗi nên chỉ cần sờ đến là biết ngay lỗi sẽ xảy ra ở đâu mà. :)

Mình sẽ cố gắng khắc phục những vấn đề đã nêu.

Thanks !
 
3. Có rất nhiều thao tác rất bình thường (save, thoát, v.v...) (2 nút này đồng thời là nút SAVE - cho nên hơi lâu) chạy chả hiểu sao ... lâu thế và 90% các thao tác như vậy dẫn đến treo Excel (hình như nó ghi vào file Excel). Tôi thường thao tác vài cái thì ... treo excel (hay là tôi chưa quen làm việc với Excel nhỉ???). Lần nào Excel của tôi mở các chương trình có VBA là y như rằng Excel của tôi cứ lăn quay ra chết (Đúng là bác chưa quen với sử dụng ex rồi)
Còn nữa, đây đúng là vấn đề ... tệ nhất của các ứng dụng trên Excel. Tức là làm xong thì phải ... save file (trong khi các CSDL khác ko có khái niệm này, chỉ cần record added, updated nhoằng cái là xong). Mà ... save file của Excel thì lâu dã man (cứ thử với file Excel >= 5Mbs thì biết). Cái này thì ko chỉ tớ kêu mà các em sài Excel với dữ liệu kế toán nhớn nhớn 1 chút thường hay kêu trời lên.

Tuy nhiên, tớ thấy cái báo giá, hoặc các files có dữ liệu cần phải tính toán (như cái project costing estimate, simple project plan,... mà tớ hay làm), và dung lượng chỉ khoảng vài trăm Kbs mà làm trên excel thì nhất quả đất (chả nên làm trên phần mềm nào khác cả). :D
 
Lần chỉnh sửa cuối:
File mới cập nhật, sửa & bổ sung một số chức năng trong phần DANH MỤC + Một số chức năng khác.

Bây giờ các bạn vào mở file' Từ Menu chính của chương trình chọn vào nút DANH MỤC sau đó chọn các danh mục như: Phụ tùng, Máy móc thiết bị, Giấy đề nghị, Tìm theo mã hàng ... để test thử hộ tôi nhé.
 

File đính kèm

Lần chỉnh sửa cuối:
Cám ơn rất nhiều nhé. Ráng cho mấy ẻm nhờ.
"Người thổi và hàng tổng", mệt chưa? Phải chi ta giúp được gì nhỉ! Khổ là về form ta chưa rành.
 
vungoc đã viết:
File mới cập nhật, sửa & bổ sung một số chức năng trong phần DANH MỤC + Một số chức năng khác.

Bây giờ các bạn vào mở file' Từ Menu chính của chương trình chọn vào nút DANH MỤC sau đó chọn các danh mục như: Phụ tùng, Máy móc thiết bị, Giấy đề nghị, Tìm theo mã hàng ... để test thử hộ tôi nhé.

Mình vẫn thích cách tìm danh mục cũ hơn.
Đây là File đã sửa tốc độ hiển thị của Danh mục. Bác VuNgoc xem nhé.

Ngày mai mình sẽ cải thiện về tốc độ lưu File lại.
Thân!
 

File đính kèm

Cảm ơn Mr. Hiếu, nhưng mình thấy tốc độ vẫn chậm bạn ạ !

Với lại cái file "Quan ly kho phu tung (Ver02) 24-10-2007" mình đã sửa đổi rất nhiều, nếu có sửa gì bạn vui lòng sửa vào trong file này dùm mình với nhé.

Cảm ơn nhiều !
 
Mr Okebab đã viết:
Vâng, Bác Duyệt làm nhiều rồi, nhưng bác ấy cứ như là Yang Can Cook ấy.
Làm món thì cực ngon (em khỏi phải quảng cáo), luôn miệng nói là : Yang làm được, các bạn cũng làm được.
Híc híc, em làm theo bác ấy mà được thì em . . chết liền. Cũng bởi bì em . . ngu quá đấy mà.+-+-+-++-+-+-+
Với ý định đã hình thành từ lâu, nhưng vì VEC còn mới quá, chúng ta sẽ có khoản hai buổi chuyên đề về ADO.

To: Vungoc,
Dạo này đang chuẩn bị cho buổi sinh hoạt lần 2 nên chưa thể làm cùng em được. !$@!! Thông cảm nha.

Tôi hy vọng rằng sau khi xong chuyên đề ADO, các bạn sẽ phát triển ứng dụng của mình tốt hơn.

Lê Văn Duyệt
 
Quản lý kho vật tư

Xin chào các bạn . Tôi cũng viết một chương trình nhỏ về quản lý vật tư hiện đang áp dụng trong công ty . xin gởi lên cho các bạn góp ý .
 

File đính kèm

Hình như lần trước tớ có nói về các lỗi mà bạn vungngoc chưa nhận ra nhỉ? Lần này vào mọi thứ y trang như lần trước. Đây, tôi attach cái file lỗi để bạn xem.

Bạn làm như sau thì sẽ thấy lỗi:

- Vào chức năng "Báo cáo"
- Chọn một nhà cung ứng phụ tùng từ Combo NhaCungUng
- Sau đó xóa nhà cung ứng đó khỏi Combo Text đi --> Lỗi Runtime xảy ra.

Lý do lỗi: Sau khi xóa (Clear Text trên Combo) thì NNhaCungUng.ListIndex = -1

Và khi đó cái dòng lệnh sẽ bị lỗi
S111.Range("F5") = Me.NNhaCungUng.Column(1)

Bạn cần phải sửa là:

Mã:
   [B]If NNhaCungUng.ListIndex <> -1 Then[/B]
        S111.Range("E5") = Me.NNhaCungUng
        S111.Range("F5") = Me.NNhaCungUng.Column(1)
    End If

Tóm lại, trước khi bạn làm cái gì cũng phải kiểm tra trước khi thực hiện. Trước khi xóa 1 file phải kiểm tra xem file đó có tồn tại ko, có readonly ko, có v.v... ko rồi mới Kill file. Bạn hiểu ý tôi chứ???? (Đây cũng là 1 lý do mà các PM trong nước thường xuyên xảy ra lỗi "lặt vặt" kiểu này - Mà khách hàng, người sử dụng thì cứ thấy lỗi là chán rồi cho dù lỗi nhỏ hay lỗi lớn)

Một vấn đề nữa. Khi tôi vào 1 form hầu như ko thấy giá trị mặc định đâu cả. Tỷ như lúc vào form danh mục, ko hiểu cái danh sách phía bên phải là của danh mục nào (vì chả có cái option bên trái nào được chọn)??? Đây có thể đối với tôi là 1 lỗi trầm trọng, ko biết với các bạn thì đó có phải là 1 lỗi hay ko. Tôi bắt lỗi phần mềm hơi chặt (chỉ sai chính tả thôi tôi cũng coi đó là 1 lỗi ko thể chấp nhận được rồi).

Tương tự như vậy, khi vào form báo cáo, 2 ô Từ ngày, Đến ngày cần phải có giá trị mặc định (đầu kỳ hiện thời tới ngày hôm nay hoặc ngày cuối kỳ). Cũng ở màn hình Báo cáo này, lựa chọn (Option) Nhập/Xuất lại ko được mặc định lựa chọn. Vả lại, các báo cáo nhập/xuất này chưa mang tính tổng quát. Có thể yêu cầu chỗ bạn chỉ đơn giản là xem báo cáo NX của từng đối tượng cụ thể chứ ko xem báo cáo dạng Tổng hợp/Chi tiết.

Ý kiến này có vẻ làm bạn sẽ phật lòng đây: Việc nhập dữ liệu có vẻ ko được logic và hợp lý. Tớ vào form Nhập hàng mà chả biết thế nào là thêm mới 1 chứng từ, thế nào là sửa chứng từ, cập nhật là gì, v.v... và sau khi thêm mới/sửa thì nó lưu vào đâu (tức là danh sách chứng từ ở đâu) và xem lại chứng từ bằng cách nào.

Bạn thử suy nghĩ cách làm như thế này xem:
1/ Màn hình "Hiển thị danh sách":
a. Định nghĩa: Đây là 1 đối tượng (nôm na gọi là Form đi cho đơn giản, còn tớ thì viết hẳn thành 1 object) cho phép list tất cả các đối tượng cần quản lý trong hệ thống như: Các danh mục, các chứng từ....
b. Các actions trên màn hình hiển thị danh sách:
- Thêm mới: Gọi 1 form (màn hình "chi tiết") để nhập mới đối tượng tương ứng
- Sửa: Gọi 1 form (màn hình "chi tiết") để sửa một đối tượng hiện thời trong màn hình danh sách
- Xóa: Xóa đối tượng hiện thời trong màn hình danh sách
- Lọc: Cho phép lọc theo tất cả các thông tin liên quan tới đối tượng được hiển thị
- In: Cho phép in danh sách đối tượng hiện thời (kể cả sau khi lọc)
c. Chú ý:
- Các nút Sửa/Xóa/In phải mờ đi (Enable = false) khi danh sách rỗng (Rows = 1 - include header row)
- Không refresh cả danh sách sau khi thêm mới hoặc sửa đối tượng mà chỉ insert/update current row

2. Màn hình "chi tiết"

Thôi tớ phải làm cho khách hàng cái đã, lúc nào rảnh viết tiếp

P/S: Có lẽ tớ chỉ xem qua về phần mềm đến thế thôi. Nhưng tớ khuyên bạn là: Hãy nên tham khảo các phần mềm có tính thương mại xem cách họ bố trí như thế nào (tốt nhất nên xem các PM của nước ngoài ấy).
 

File đính kèm

  • Combo Error.jpg
    Combo Error.jpg
    80.8 KB · Đọc: 434
quangiang đã viết:
Xin chào các bạn . Tôi cũng viết một chương trình nhỏ về quản lý vật tư hiện đang áp dụng trong công ty . xin gởi lên cho các bạn góp ý .

- Nút "thoát" chỉ được sử dụng khi thoát hẳn khỏi chương trình, còn nếu chỉ Close 1 cái cửa sổ thì người ta dùng "Đóng".
- Khi sửa 1 danh mục (mặt hàng chẳng hạn) thì lại báo trùng mã. Sửa đúng danh mục đó chứ có phải thêm mới đâu (Lúc check trùng mã thì phải chừa cái mã đang sửa ra).
- Các chứng từ ko có dạng Master/Detail. --> KO hợp lý rồi.
 
Trước hết mình xin cảm ơn smbsolutions đã có những đóng góp rất thiết thực dưới góc độ nhà chuyên môn. vungoc cũng nên tạo bẫy lỗi và kiểm tra trước nhất là đối với xóa dòng dễ dẫn đến lỗi. Thật tình mình thấy file này giao diện rất đẹp ( Không sến) và xử lý nhanh. Mình chưa có điều kiện xem hết nhưng thấy các báo cáo bạn chưa dùng lệnh dùng màn hình vì vậy vẫn còn giật khi thực hiện lệnh. Và mình không biết trở lại form màn hình chính thế nào khi đã vào sheet. Thứ hai là các form dùng cho màn hình >=15"" chứ màn hình 14" xem như chịu chết các nút lệnh phía dưới form không thực hiện được. Chúc bạn thành công.
 
Cải thiện về tốc độ lập báo cáo

Cảm ơn bác Vungoc đã gửi tặng thêm cho GPE một ứng dụng kinh tế vầ rất thực tế. Đã có nhiều bài góp ý về bố cục, giao diện của ứng dụng rồi. Mình xin góp ý thêm về tốc độ thực hiện của chương trình, đặc biệt trong báo cáo.

Hiện nay chương trình có một báo cáo "BÁO CÁO TỔNG HỢP NHẬP - XUẤT - TỒN PHỤ TÙNG" mình thấy tốc độ thực hiện quá chậm, số bản ghi của sheet DATA chỉ mới có 190 thôi, khi làm thực tế thì con số này phải gấp 100 lần (vẫn còn ít).

Có 3 nguyên nhân chính làm cho thủ tục báo cáo chạy chậm:
1) Do Name động
Trong tất cả các name dùng trong công thức (SumProduct) đều là name động

Mã:
DataSo=COUNTA(DATA!$B$1:$B$65000)
DataNgay=OFFSET(DATA!$C$2,0,0,DataSo,1)
DataPhieu=OFFSET(DATA!$B$2,0,0,DataSo,1)
...
Data*==OFFSET(DATA!$***$2,0,0,DataSo,1)

Cứ khi trong công thức dùng tới các name DataNgay, DataPhieu,...thì đều phải chạy hàm COUNTA (vì trong name có tham chiếu DataSo=COUNTA(DATA!$B$1:$B$65000) ). Với một bảng tính nhỏ, , ít dữ liệu, ít tính toán thống kê thì việc tạo name này rất linh động và thuận tiện nhưng với một Chương trình quản trị dữ liệu thì đây là giải pháp thực sự là không tốt.

2) Chưa ngăn các sự kiện của Workbook và Sheet
Mỗi một lệnh Range().Select hay gán giá trị Range().Value thì một số các sự kiện của Excel sẽ chạy vì vậy cần phải chặn chúng lại khi không cần thiết.
Để thực hiện, dùng theo cách dưới đây:
Mã:
Sub ThuTuc
On Error Goto EndSub
   Application.EnableEvents = False
   ....
   Các lệnh
   ....
   'Cuối thủ tục
   '
EndSub:
   Application.EnableEvents = True
   If Err <> 0 Then MsgBox Err.Description, vbCritical, "Error: THNXT " & Err.Number
End Sub


3) Dư thừa công thức - Nguyên nhân chính
Trong sổ tổng hợp Vungoc lập công thức tính cho cả 1094 mã phụ tùng. Số cột phải tính là 8:
TDK_SLG|TDK_Giatri|Nhap_SLG|Nhap_Giatri|Xuat_SLG|Xuat_Giatri|TCK_SLG|TCK_Giatri|
6 cột đầu công thức dùng hàm SumProduct(tính trong một vùng DATA có 190 dòng). Số công thức báo cáo của Vungoc phải thực hiện là 8*1094 = 8752 (tính một cách tương đối).
-->Thực tế trong sheet DATA, số mã phụ tùng chỉ có 31 mã khác nhau. Như vậy, báo cáo chỉ phải tính số công thức là 8*31=248 .
-->Theo phân tích trên thì số công thức đã tính bị thừa là 8752-248 = 8504:=\+


Mình đã viết thêm một số hàm và thủ tục phục vụ cho việc lập báo cáo trong Excel, viết lại thủ tục THXNT_ext tốc độ tăng nhanh hơn thủ tục THXNT trước đây gấp nhiều lần (~+58.29 lần).

Thêm:
Sub CreateDataName() 'Tạo tên cho DATA, thủ tục này chạy trong nút "Save" của 2 form FrNhap, FrXuat
Function GetEndRow(ByVal Sh As Worksheet, Optional ByVal ColumnBase As String = "A") As Long 'Xác định dòng cuối
Sub PasteIDs(ByVal FromRange As Range, ByVal CellToPaste As Range) 'Nhận danh sách duy nhất
Sub THXNT_ext() 'Tính nhập xuất tồn


Chúc cho chương trình của bác Vungoc ngày càng hoàn thiện!
 

File đính kèm

Lần chỉnh sửa cuối:
TuanVNUNI đã viết:
3) Dư thừa công thức - Nguyên nhân chính
Trong sổ tổng hợp Vungoc lập công thức tính cho cả 1094 mã phụ tùng. Số cột phải tính là 8:
TDK_SLG|TDK_Giatri|Nhap_SLG|Nhap_Giatri|Xuat_SLG|Xuat_Giatri|TCK_SLG|TCK_Giatri|
6 cột đầu công thức dùng hàm SumProduct(tính trong một vùng DATA có 190 dòng). Số công thức báo cáo của Vungoc phải thực hiện là 8*1094 = 8752 (tính một cách tương đối).
-->Thực tế trong sheet DATA, số mã phụ tùng chỉ có 31 mã khác nhau. Như vậy, báo cáo chỉ phải tính số công thức là 8*31=248 .
-->Theo phân tích trên thì số công thức đã tính bị thừa là 8752-248 = 8504
Chúc cho chương trình của bác Vungoc ngày càng hoàn thiện!
Vâng, quả thực là nhanh hơn thật.
Em mới xem qua Sheet TH XNT và có một số góp ý thế này :
  • Các giá trị bác nên copy dán giá trị lên thôi, ta không nên để công thức "sống" như thế. Dung lượng File sẽ tăng và việc lưu cũng như tính toán sẽ chậm đi (Khi kích hoạt sự kiện tính toán cả File)
  • Việc dùng AF để lọc ra danh mục duy nhất làm tăng tốc độ tính toán rất nhiều. Tuy nhiên đây cũng chính là yếu điểm của nó :
    • Tiêu đề cột trên báo cáo phải giống trên Data : Mã Phụ Tùng
    • Báo cáo chỉ tính toán được các mã có phát sinh (trong Data) mà lại không tính toán được các mã không phát sinh nhưng lại có số dư - Đây là cái chính yếu
  • Mã cuối cùng luôn bị xóa đi (cái này thì đơn giản, tăng thêm 1 dòng thôi)
  • Chưa có ghi ra bộ phận trong cột ghi chú (cũng đơn giản, chỉ thêm một công thức nữa thôi)
Cảm ơn bác nhiều!!

Thân!
 
Lần chỉnh sửa cuối:
TuanVNUNI [B đã viết:
1) Do Name động[/B]
Trong tất cả các name dùng trong công thức (SumProduct) đều là name động

Mã:
DataSo=COUNTA(DATA!$B$1:$B$65000)
DataNgay=OFFSET(DATA!$C$2,0,0,DataSo,1)
DataPhieu=OFFSET(DATA!$B$2,0,0,DataSo,1)
...
Data*==OFFSET(DATA!$***$2,0,0,DataSo,1)
Cứ khi trong công thức dùng tới các name DataNgay, DataPhieu,...thì đều phải chạy hàm COUNTA (vì trong name có tham chiếu DataSo=COUNTA(DATA!$B$1:$B$65000) ). Với một bảng tính nhỏ, , ít dữ liệu, ít tính toán thống kê thì việc tạo name này rất linh động và thuận tiện nhưng với một Chương trình quản trị dữ liệu thì đây là giải pháp thực sự là không tốt.

Riêng cái này (dùng công thức cho các bảng tổng hợp, báo cáo ) mong bác cho giải pháp ???
Chạy vòng lặp (chạy 1 lần cả Data) thì nhanh hơn, tuy nhiên lập trình vất vả hơn, hơn nữa mỗi lần thay đổi thì sửa oải lắm.--=0--=0
Mong bác cho giải pháp!!!

Thân!
 
Các giá trị bác nên copy dán giá trị lên thôi, ta không nên để công thức "sống" như thế. Dung lượng File sẽ tăng và việc lưu cũng như tính toán sẽ chậm đi (Khi kích hoạt sự kiện tính toán cả File)

Mình cũng quên chưa xoá dấu phảy (') trong đoạn
Mã:
    With Range("A9:N" & i + 2)
        [COLOR="Green"][COLOR="Red"]'[/COLOR].Value = .Value[/COLOR]
    End With

Chỉ cần chữa thành
Mã:
    With Range("A9:N" & i + 2)
        .Value = .Value
    End With

Báo cáo chỉ tính toán được các mã có phát sinh (trong Data) mà lại không tính toán được các mã không phát sinh nhưng lại có số dư - Đây là cái chính yếu

Trong công thức vẫn tính cả tồn đầu và tồn cuối mà.

Riêng cái này (dùng công thức cho các bảng tổng hợp, báo cáo ) mong bác cho giải pháp ???
Chạy vòng lặp (chạy 1 lần cả Data) thì nhanh hơn, tuy nhiên lập trình vất vả hơn, hơn nữa mỗi lần thay đổi thì sửa oải lắm.
Mong bác cho giải pháp!!!

Vùng chỉ thay đổi khi ta thêm/xoá phiếu N/X. Sau mỗi lần như vậy thì cho update lại các Name trong table đó, chạy thủ tục "CreateDataName" cũng nhanh lắm. Nếu giải pháp dùng công thức để lập sổ tổng hợp thì nên dùng Name tĩnh (như mình đã làm trong thủ tục "THNXT_ext". Mình đã nghiên cứu, nếu vẫn các lệnh trong thủ tục "THNXT" trước đay chỉ cần thay Name động (tham chiếu bởi hàm OffSet) thành Name tĩnh thì tốc độ đã tăng gấp đôi!

Giải pháp mà mình đưa ra trong thủ tục "THNXT_ext" là mọt trong những giải pháp tối ưu, có thể áp dụng chung cho tất cả các dạng báo cáo TH mà lại dễ. Tuy nhiên, số mã mã phụ tùng tham gia trong sheet DATA càng nhiều thì tốc độ càng chậm vì vẫn phải tính tổng độc lập cho từng mã. Mình vẫn còn một chiêu nữa còn nhanh hơn cái đã nói ở trên nhiều kể cả khi khối dữ liệu lớn, mình cũng dùng cách "chạy vòng lặp (chạy 1 lần cả Data) " không biết có giống cách của Mr Okebab không? Nhưng quả thật cách này viết code vất vả và tính tổng quát không cao lắm (mình định viết một bài về cái này nhưng vì hơi khó trình bày nên chưa viết).

Để giảm bới việc lập trình khi có sự sửa chữa về CSDL, tất cả cách lệnh phải làm việc trên các biến và hằng. Trong code không nên chỉ rõ cụ thể giá trị mà nên thông qua biến hoặc hằng số.
Ví dụ đơn giản thế này:
Range("A9:N" & EndRow).ClearContents
Range("C9:N"...
.......
Nên viết thành

Const StartRow = 9
....
Range("A" & StartRow & ":N & EndRow).ClearContents

Nếu sau này sửa lại cấu trúc của báo cáo dòng bắt đầu là dòng 11 thì chỉ cần thay Const StartRow = 11 là tất cả chạy đúng theo logic.

Thực tế trong một ứng dụng quản trị thì thời gian để tạo báo cáo sẽ chiếm 2/3 của cả chương trình. Vì vậy, nếu không chọn được một giải pháp tổng quát thì công việc coding thực sự rất vất vả mà hiệu quả sẽ vẫn không cao. Mình hay dùng kỹ thuật T-SQL, hình như ở đâu đó trên diễn đàn mình cũng khuyên mọi người hướng nghiên cứu về cái này nhưng không thấy ai hưởng ứng? Thực sự nó không khó, chỉ là do mọi người ngại phải thay đổi thói quen trước đây mà thôi!
 
TuanVNUNI đã viết:
Trong công thức vẫn tính cả tồn đầu và tồn cuối mà.
Bác đọc lại nhé :

Báo cáo chỉ tính toán được các mã có phát sinh (trong Data) mà lại không tính toán được các mã không phát sinh nhưng lại có số dư
Tức là với mã có mặt trong Data thì OK. Còn mã không (hoặc chưa) có trong Data, nhưng lại có số dư trong Danh Mục thì lại không tính được.




Vùng chỉ thay đổi khi ta thêm/xoá phiếu N/X. Sau mỗi lần như vậy thì cho update lại các Name trong table đó, chạy thủ tục "CreateDataName" cũng nhanh lắm. Nếu giải pháp dùng công thức để lập sổ tổng hợp thì nên dùng Name tĩnh (như mình đã làm trong thủ tục "THNXT_ext". Mình đã nghiên cứu, nếu vẫn các lệnh trong thủ tục "THNXT" trước đay chỉ cần thay Name động (tham chiếu bởi hàm OffSet) thành Name tĩnh thì tốc độ đã tăng gấp đôi!
Cái này có lẽ là vậy, để em thử xem sao.



Giải pháp mà mình đưa ra trong thủ tục "THNXT_ext" là mọt trong những giải pháp tối ưu, có thể áp dụng chung cho tất cả các dạng báo cáo TH mà lại dễ. Tuy nhiên, số mã mã phụ tùng tham gia trong sheet DATA càng nhiều thì tốc độ càng chậm vì vẫn phải tính tổng độc lập cho từng mã. Mình vẫn còn một chiêu nữa còn nhanh hơn cái đã nói ở trên nhiều kể cả khi khối dữ liệu lớn, mình cũng dùng cách "chạy vòng lặp (chạy 1 lần cả Data) " không biết có giống cách của Mr Okebab không? Nhưng quả thật cách này viết code vất vả và tính tổng quát không cao lắm (mình định viết một bài về cái này nhưng vì hơi khó trình bày nên chưa viết).
Chắc là giống thôi (ở cách làm, còn từng dòng code thì . . . em sao bằng bác được!!--=0)



Để giảm bới việc lập trình khi có sự sửa chữa về CSDL, tất cả cách lệnh phải làm việc trên các biến và hằng. Trong code không nên chỉ rõ cụ thể giá trị mà nên thông qua biến hoặc hằng số.
Ví dụ đơn giản thế này:
Range("A9:N" & EndRow).ClearContents
Range("C9:N"...
.......
Nên viết thành

Const StartRow = 9
....
Range("A" & StartRow & ":N & EndRow).ClearContents

Nếu sau này sửa lại cấu trúc của báo cáo dòng bắt đầu là dòng 11 thì chỉ cần thay Const StartRow = 11 là tất cả chạy đúng theo logic.
Thay vì số 9, lại viết StartRow, có lẽ dài dòng hơn!!!:=\+




Thực tế trong một ứng dụng quản trị thì thời gian để tạo báo cáo sẽ chiếm 2/3 của cả chương trình. Vì vậy, nếu không chọn được một giải pháp tổng quát thì công việc coding thực sự rất vất vả mà hiệu quả sẽ vẫn không cao. Mình hay dùng kỹ thuật T-SQL, hình như ở đâu đó trên diễn đàn mình cũng khuyên mọi người hướng nghiên cứu về cái này nhưng không thấy ai hưởng ứng? Thực sự nó không khó, chỉ là do mọi người ngại phải thay đổi thói quen trước đây mà thôi!
Em hoàn toàn nhất trí và sẽ cố gắng!!!

Cảm ơn bác .

Thân!
 
Tức là với mã có mặt trong Data thì OK. Còn mã không (hoặc chưa) có trong Data, nhưng lại có số dư trong Danh Mục thì lại không tính được.

Theo cách làm của mình thì số dư đầu để trong DATA chứ không để trong danh mục, làm vậy dữ liệu tập trung dễ dàng cho việc tổng hợp. Trong file mình gửi đã chuyển số dư trong danh muc vào sheet DATA với ngày 31/13/06 (dư đầu của năm 2007). Cơ sở phân biệt Dư đầu, Phát sinh là theo ngày tháng.


Chắc là giống thôi (ở cách làm, còn từng dòng code thì . . . em sao bằng bác được!!)

Mr Okebab khiêm tốn quá! Khi viết bài góp ý trên, mình chỉ nhắm đưa ra giải pháp về tốc độ để mọi người tham khảo chứ Không có ý so sánh hơn thấp. Không dám đâu!:=\+

Thay vì số 9, lại viết StartRow, có lẽ dài dòng hơn!!!

Nếu viétcode dài nhưng nó đảm bảo hệ thống chặt chẽ thì vẫn nên làm.
 
Chữ đỏ là của em !!! (Chiêu này học bác Vũ Ngọc)--=0--=0

TuanVNUNI đã viết:
Theo cách làm của mình thì số dư đầu để trong DATA chứ không để trong danh mục, làm vậy dữ liệu tập trung dễ dàng cho việc tổng hợp. Trong file mình gửi đã chuyển số dư trong danh muc vào sheet DATA với ngày 31/13/06 (dư đầu của năm 2007). Cơ sở phân biệt Dư đầu, Phát sinh là theo ngày tháng.

Vâng, đây cũng là giải pháp của em khi có số dư bên danh mục. Giả sử ngày bắt đầu là ngày 1/1/07 thì lấy hết số dư đầu nhập vào Data vào ngày 31/12/2006. Như vậy sẽ tiện theo dõi hơn.
Còn cái ngày 31/13/06 : Em tra lịch hoài mà tìm không thấy!!--=0--=0



Mr Okebab khiêm tốn quá! Khi viết bài góp ý trên, mình chỉ nhắm đưa ra giải pháp về tốc độ để mọi người tham khảo chứ Không có ý so sánh hơn thấp. Không dám đâu!:=\+

Em lại được ngồi trên vai người khổng lồ rồi. Sướng ghê!!}}}}}}}}}}



Nếu viétcode dài nhưng nó đảm bảo hệ thống chặt chẽ thì vẫn nên làm.
Em lại chưa thấy chặt chẽ hơn chỗ nào cả. Con số 9 hay 11 hay 20 chỉ là 1 hằng số, mỗi Sub sử dụng 1 lần, thay vì phải : StartRow = 9 thì em cho = 9 luôn, thế thì hệ thống ảnh hưởng gì nhỉ.
Quan điểm của em là : Nhanh (về tốc độ, về viết code), đơn giản, hiệu quả và không gây lỗi.
Có thể do trình độ nên em chỉ nhìn được đến thế thôi, mong bác chỉ giáo thêm.

Cảm ơn bác nhiều.

Thân!
 
Cảm ơn sự đóng góp rất cụ thể và rất giá trị của bác TuanVNUNIMr.Okebab ***&&%_)(#;

Mình xin ghi nhận ý kiến của bác để cải tiến chương trình ngày càng hoàn thiện hơn.

Xin cảm ơn 2 bác / Chúc sức khỏe và thành công !
(Mong sớm gặp lại)

Thân mến !
 
Lần chỉnh sửa cuối:
Không biết tôi có làm sai chỗ nào không mà sao nó chạy nhanh lắm, nhanh hơn cách của Tuân luôn.
Add 1 sh và tên là S99 (tmp)
Copy dữ liệu thỏa dk vào S99. Đặt tên name, dùng Sumif lấy kết quả, xóa name.
Vũ Ngọc tham khảo.
PHP:
Option Explicit
    Dim HC As Long, ActSh As Worksheet
    Dim i As Long, j As Long
    Dim NgayDau As Date, NgayCuoi As Date
    Dim T1, T2
    Dim DuLieu As Range, MaPTBC As Range, NgayCT As Range, MaHang As Range
Sub TaoNXT()

Set ActSh = S99
ActSh.Visible = False
    With Application
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
        .EnableEvents = False
    End With
    T1 = timeGetTime
    S109.Select
    With S109
        .Range("A9:O5000").ClearContents
        With Range("A10:O5000")
        Call NLine
        End With
    End With
    If S104.Range("B2") = "" Then
        MsgBox "No Data"
    Else 'chac chan data co du lieu
        HC = S104.Range("B1").End(xlDown).Row - 1
    End If
    NgayDau = S109.Range("G5").Value
    NgayCuoi = S109.Range("I5").Value
    'MsgBox HC
    With ActSh 'lay dulieu qua tmp
        .Range("A1:L1000").ClearContents
        .Range("A1:B" & HC + 1).Value2 = S104.Range("B1:C" & HC + 1).Value2
        .Range("C1:C" & HC + 1).Value = S104.Range("J1:J" & HC + 1).Value
         'Gan SL + Tien NX
        .Range("D1") = "SLNhap"
        .Range("E1") = "SLXuat"
        .Range("F1") = "GTNhap"
        .Range("G1") = "GTXuat"
        .Range("H1") = "SLTonDau"
        .Range("I1") = "GTTonDau"
         For i = 2 To HC + 1
        If .Range("B" & i).Value >= NgayDau And .Range("B" & i).Value <= NgayCuoi Then
            If Left(.Range("A" & i).Value, 2) = "PN" Then
                .Range("D" & i) = S104.Range("K" & i)
                .Range("F" & i) = S104.Range("M" & i)
            Else
                .Range("E" & i) = S104.Range("K" & i)
                .Range("G" & i) = S104.Range("M" & i)
            End If
        ElseIf .Range("B" & i).Value < NgayDau Then
            If Left(.Range("A" & i).Value, 2) = "PN" Then
                .Range("H" & i) = S104.Range("K" & i)
                .Range("I" & i) = S104.Range("M" & i)
            Else
                .Range("H" & i) = -S104.Range("K" & i)
                .Range("I" & i) = -S104.Range("M" & i)
            End If
        End If
    Next i
    End With
    Set DuLieu = ActSh.Range("A2:I" & HC + 1)
    'Sort lai du lieu
    With DuLieu
       .Sort Key1:=.Range("B2"), Order1:=xlAscending, Key2:=.Range("A2") _
        , Order2:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:= _
        False, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal, DataOption2 _
        :=xlSortNormal
    End With
    Set NgayCT = ActSh.Range("B2:B" & HC + 1)
    'Xoa nhung du lieu > ngaycuoi
    HC = WorksheetFunction.CountIf(NgayCT, "<=" & CLng(NgayCuoi)) + 1
    If HC > 0 Then
        ActSh.Range("A" & HC + 1 & ":I5000").ClearContents
    End If
    Set MaHang = ActSh.Range("C1:C" & HC + 1)
    With MaHang
        .AdvancedFilter Action:=xlFilterCopy, CopyToRange:=ActSh.Range( _
        "K1"), Unique:=True
    End With
    HC = ActSh.Range("K65000").End(xlUp).Row
    'MsgBox i
    ActSh.Range("K2:K" & HC).Name = "MaPTBC"
    With Range("MaPTBC")
        .Sort Key1:=ActSh.Range("K2"), Order1:=xlAscending, Header:=xlGuess, _
        OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
        DataOption1:=xlSortNormal
    End With
    'Dan vao NXT
    S109.Range("B9:B" & HC + 7).Value = ActSh.Range("MaPTBC").Value
    With ActSh ' Xoa name
        .Range("MaPTBC").ClearContents
        .Range("Extract").Delete
        .Names("Extract").Delete
    End With
    With Application
        .ActiveWorkbook.Names("MaPTBC").Delete
    End With
    HC = ActSh.Range("B65000").End(xlUp).Row
    'MsgBox HC
    'Gan lai hang cuoi cho ton dau ky, dat ten name
    With ActSh
        .Range("D2:D" & HC + 1).Name = "SLNhap"
        .Range("E2:E" & HC + 1).Name = "SLXuat"
        .Range("F2:F" & HC + 1).Name = "GTNhap"
        .Range("G2:G" & HC + 1).Name = "GTXuat"
        .Range("C2:C" & HC + 1).Name = "MaHang"
        .Range("H2:H" & HC + 1).Name = "SLTonDau"
        .Range("I2:I" & HC + 1).Name = "GTTonDau"
    End With
    
    'Dong cuoi cua NXT TH
    i = S109.Range("B65000").End(xlUp).Row
    'Gan so lieu vao NXTTH
    With S109
        .Range("G9:G" & i).FormulaR1C1 = "=SUMIF(MaHang,RC2,SLTonDau)"
        .Range("H9:H" & i).FormulaR1C1 = "=SUMIF(MaHang,RC2,GTTonDau)"
        .Range("I9:I" & i).FormulaR1C1 = "=SUMIF(MaHang,RC2,SLNhap)"
        .Range("J9:J" & i).FormulaR1C1 = "=SUMIF(MaHang,RC2,GTNhap)"
        .Range("K9:K" & i).FormulaR1C1 = "=SUMIF(MaHang,RC2,SLXuat)"
        .Range("L9:L" & i).FormulaR1C1 = "=SUMIF(MaHang,RC2,GTXuat)"
        .Range("M9:N" & HC + 7).FormulaR1C1 = "=RC[-6]+RC[-4]-RC[-2]"
        .Range("A9:A" & HC + 7).FormulaR1C1 = "=IF(SUM(RC7:RC9)>0,1,"""")"
        'gan ten hang va DVT
        With Range("C9:C" & i)
            .FormulaR1C1 = "=VLOOKUP(RC2,DMPTArray,2,0)"
        End With
        With Range("D9:D" & i)
            .FormulaR1C1 = "=VLOOKUP(RC2,DMPTArray,4,0)"
        End With
        With Range("O9:O" & i)
            .FormulaR1C1 = "=VLOOKUP(RC2,DMPTArray,5,0)"
        End With
    End With
     
    With S109.Range("A9:O" & HC + 7)
       .Value = .Value
        .Sort Key1:=.Range("A9"), Order1:=xlAscending, Key2:=.Range( _
            "B9"), Order2:=xlAscending, Header:=xlNo, OrderCustom:=1, MatchCase _
            :=False, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal, _
            DataOption2:=xlSortNormal
    End With

    i = S109.Range("A65000").End(xlUp).Row
    If i < 10 Then i = 10
    S109.Range("A" & i + 1 & ":P" & HC + 7).ClearContents
       
    With Range("A9:A" & i)
        .FormulaR1C1 = "=ROW()-8"
        .Value = .Value
    End With
    With Range("E" & i + 2 & ":N" & i + 2)
        .FormulaR1C1 = "=SUM(R9C:R[-1]C)"
        .Value = .Value
    End With
    Range("C" & i + 2) = UCase("T" & ChrW$(7893) & "ng " & "c" & ChrW$(7897) & "ng")
'    Range("E9:F9").EntireColumn.Hidden = True
    S109.Range("A9:O" & i + 1).Select
    Call YLine
    S109.Range("A" & i + 2 & ":O" & i + 2).Select
    'MsgBox i
    Call YLineTC
    ActSh.Cells.ClearContents
    Range("D5").Select
With Application
    .Names("SLNhap").Delete
    .Names("SLXuat").Delete
    .Names("GTNhap").Delete
    .Names("GTXuat").Delete
    .Names("MaHang").Delete
    .Names("SLTonDau").Delete
    .Names("GTTonDau").Delete
End With
ActSh.Visible = False
With Application
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
        .EnableEvents = False
End With
  
    T2 = timeGetTime
    MsgBox "Thuc hien het " & T2 - T1 & " millisecond(s)"
    
End Sub
 
Theo cách của bác ThuNghi dùng hàm SumIf nhưng công thức bị sai vì không có điều kiện về ngày tháng (từ ngày....đến....?), riêng cái này đã giảm bới điều kiện phân tích của công thức nên nó sẽ chạy nhanh hơn.
Bác ThuNghi thử làm hoàn thiện lại các công thức về SumIf xem thế nào? Mình vẫn tin là dùng SumIf sẽ làm nhanh hơn.
 
nhưng công thức bị sai vì không có điều kiện về ngày tháng (từ ngày....đến....?)
Có điều kiện về ngày mà, làm theo cách của Bác Tuân, số tồn đầu năm đưa vào trong sh Data, với ngày là 31/12/2006 và số CT là PN0000
Với lại phần số tồn đầu năm nên đưa vào 1 sh TonKhoDauKy thì hay hơn. Tính tồn theo hàng tháng.
Ngày....SoPhieu....MaPT...SL...GT
For i = 2 To HC + 1
If .Range("B" & i).Value >= NgayDau And .Range("B" & i).Value <= NgayCuoi Then
If Left(.Range("A" & i).Value, 2) = "PN" Then
.Range("D" & i) = S104.Range("K" & i)
.Range("F" & i) = S104.Range("M" & i)
Else
.Range("E" & i) = S104.Range("K" & i)
.Range("G" & i) = S104.Range("M" & i)
End If
ElseIf .Range("B" & i).Value < NgayDau Then
If Left(.Range("A" & i).Value, 2) = "PN" Then
.Range("H" & i) = S104.Range("K" & i)
.Range("I" & i) = S104.Range("M" & i)
Else
.Range("H" & i) = -S104.Range("K" & i)
.Range("I" & i) = -S104.Range("M" & i)
End If
End If
Next i
 

File đính kèm

Lần chỉnh sửa cuối:
Hoá ra có đoạn tính tồn đầu ở vòng lặp For..Next mà mình không nhìn thấy.

Tuỳ vào mục đích cụ thể, có những báo cáo thì tồn đầu năm hay đầu tháng là bất dịch, nhưng nhiều báo cáo cũng như cách làm chung thì người ta hay làm thế này:

Tồn đầu kỳ < D1
D1 <= Phát sinh <= D2

D1, D2 là hai giá trị ngày xác định khoảng thời gian, như thế thì chỉ têu "Tồn đầu kỳ" cũng như "Phát sinh" không phải giữ nguyên/cố định là một tháng hay một năm nữa mà nó sẽ "động đậy". Chính vì lý do đó mà đoạn công thức của ThuNghi dưới đây chưa đảm bảo được sự "động đậy" đó?
Mã:
        .Range("G9:G" & i).FormulaR1C1 = "=SUMIF(MaHang,RC2,SLTonDau)"
        .Range("H9:H" & i).FormulaR1C1 = "=SUMIF(MaHang,RC2,GTTonDau)"
        .Range("I9:I" & i).FormulaR1C1 = "=SUMIF(MaHang,RC2,SLNhap)"
        .Range("J9:J" & i).FormulaR1C1 = "=SUMIF(MaHang,RC2,GTNhap)"
        .Range("K9:K" & i).FormulaR1C1 = "=SUMIF(MaHang,RC2,SLXuat)"
        .Range("L9:L" & i).FormulaR1C1 = "=SUMIF(MaHang,RC2,GTXuat)"
 
Tồn đầu kỳ < D1
D1 <= Phát sinh <= D2

D1, D2 là hai giá trị ngày xác định khoảng thời gian, như thế thì chỉ têu "Tồn đầu kỳ" cũng như "Phát sinh" không phải giữ nguyên/cố định là một tháng hay một năm nữa mà nó sẽ "động đậy". Chính vì lý do đó mà đoạn công thức của ThuNghi dưới đây chưa đảm bảo được sự "động đậy" đó?
Có thể cụ thể hơn?
SLTonDau, GTTonDau... sẽ được tạo lại khi D1 và D2 thay đổi mà.
Đúng ra nếu có sh TonKhoDauKy thì khi ta tính NXT sẽ lấy SL và GT tồn kho của tháng = Month(D1)-1, và chỉ lấy dữ dữ liệu từ ngày 1 của Month(D1) cho đến D2. Như vậy số DL xửa lý sẽ ít hơn. Nhưng hiện tại chưa hình dung ra.
 
ThuNghi đã viết:
Có thể cụ thể hơn?
SLTonDau, GTTonDau... sẽ được tạo lại khi D1 và D2 thay đổi mà.
Đúng ra nếu có sh TonKhoDauKy thì khi ta tính NXT sẽ lấy SL và GT tồn kho của tháng = Month(D1)-1, và chỉ lấy dữ dữ liệu từ ngày 1 của Month(D1) cho đến D2. Như vậy số DL xửa lý sẽ ít hơn. Nhưng hiện tại chưa hình dung ra.

Là như thế này bác ạ.
Từ bảng TH NXT , người ta muốn xem trong khoảng thời gian từ ngày 05/10/07 (D1) đến 22/10/07 (D2). Như yêu cầu trên thì các dữ kiện nhập và xuất trước ngày 05 sẽ tính là dư đầu kỳ ...

Dùn hàm SUMIF thì tốc độ nhanh nhưng bị giới hạn về số lượng điều kiện, vẫn có cách làm được khi dữ liệu gốc ta tạo thêm cột phụ, như thế sẽ hơi phức tạp.
 
Về hàm Sumif và hàm Sumproduct thì đã có rất nhiều bài để so sánh 2 hàm này. Cái yếu của hàm này chính là thế mạnh của hàm kia

Quả thực về tốc độ thì sumproduct không thể bì được với SUMIF về tốc độ, tuy nhiên về việc không dùng cột phụ và đặc biệt là việc linh hoạt về tổng hợp các chỉ tiêu theo nhiều điều kiện khác nhau thì SUMIF không thể bì được.

Vì vậy việc cân nhắc giữa hai hàm này nên tùy vào các TH cụ thể.
Trong TH này thì em vẫn thích dùng SUMPRODUCT hơn vì :
  1. Không làm rối CSDL
  2. Có thể tăng thêm các ĐK xử lý mà không ảnh hưởng gì
  3. Nếu có tăng thêm các nhu cầu quản lý (ở BÁO CÁO -->>DATA) thì khi đó ta lại phải vất vả với SUMIF (Có khoảng 10 báo cáo kiểu đó thì khi đó dùng sumif cũng . . . hơi mệt)
Cái quan trọng là ta phải nghĩ cách tính toán làm sao để nhanh hơn thôi (VD như Bác Tuân đã đưa ra một ý tưởng hay).

Còn việc về sô dư đầu kỳ, em thích cách của em (và bác Tuân) hơn, cho cả vào Data. Vì số dư đầu kỳ , số lũy kế kỳ trước, số phát sinh, số lũy kế đến kỳ luôn động nên giải pháp dúng Sh temp để chứa số liệu như bác ThuNghi rất khó khăn.
Việc ngày tháng thì bất kể, có thể 13/12/2006 -->> 14/05/2007
Nhu vậy thì tốt nhất là cho vào trong DATA, chứ nếu cho vào Sh riêng thì . . khó cho nhau quá.


Tất nhiên mỗi người một quan điểm và thói quen.
Đây chỉ là cách nghĩ của em, còn các bác có thể khác, vậy thì . . . mọi người cứ đi trên con đường được cho là đúng.

Mấy lời thiển cận!
Thân!
 
Thông thường thì mình vẫn dùng chứng từ có kiểu (transaction type) là OB (Opening Balance) làm chứng từ số dư đầu kỳ. Số dư đầu kỳ chia làm 2 loại, 1 loại là manual - tự nhập - thường nhập lần đầu khi áp dụng chương trình và một loại là các số dư do thực hiện các giao dịch chuyển kỳ (số dư đầu kỳ này = số dư cuối kỳ trước). Việc tách số dư đầu kỳ ra nhằm 2 lý do sau đây:

- Thứ nhất: Kỳ (accounting period) có thể được định nghĩa theo đặc thù của DN. Kỳ kế toán sẽ được assigned vào chứng từ loại OpeningBalance. Thông thường kỳ kế toán ở VN là tháng (Quý thì là gộp 3 tháng thôi). Ở các phần mềm nước ngoài có tính mở như SAP thì có thể lên tới 15 kỳ trong 1 năm tài chính. Và một năm tài chính thì có thể bắt đầu từ giữa năm hoặc đầu năm (Dependance Year hoặc Independance Year). 99% các phần mềm kế toán trong nước và 1 số phần mềm kế toán của nước ngoài đều ko thể "vượt biên ra biển khơi" cũng là do cái chuyện có thể định nghĩa kỳ kế toán kiểu này được. Đọc cái SAP Show training về cái SAP mà anh Duyệt đang dùng thì thấy riêng vụ Fiscal Year và Accounting Period nó mất ~20 trang rồi.
- Thứ 2: Trong cái rừng "Data" (GL hay sổ JournalList gì đó của các bác) thì để lấy cái số dư đầu kỳ ắt hẳn phải chậm hơn lấy từ bảng OpeningBalance kia. Việc tính số dư của các kỳ kế tiếp cho ta giải pháp về tốc độ. Thế nên, trong CSDL, có một phương pháp gọi là phi chuẩn hóa CSDL chủ yếu để tạo tốc độ mà thôi.

Sau khi có số dư của từng kỳ, việc làm báo cáo từ ngày, đến ngày kiểu "13/12/2006" (D1) --> "14/05/2007" (D2) là cực đơn giản. Chẳng thấy gặp khó khăn gì cả.
...
{
Balance1 = getBalance(D1)
Dr(D1, D2) = getDR(D1, D2) '// Phat sinh tang trong ky: D1 -> D2
Cr(D1, D2) = getCR(D1, D2) '// Phat sinh giam trong ky: D1 -> D2
Balance2 = Balance1 + Dr(D1, D2) - Cr(D1, D2)
}
...

getBalance(D1)
'// Get balance at D1
{
OB = getOB(D1)
D0 = FirstDayofPeriod(D1)
Dr(D0, D1) = getDR(D0, D1) '// Phat sinh tang trong ky: D0 -> D1
Cr(D0, D1) = getCR(D0, D1) '// Phat sinh giam trong ky: D0 -> D1
getBalance = OB + Dr(D0, D1) - Cr(D0, D1)
}

Đại khái thế, còn đối tượng để getBalance, getDR, getCR thì có thể là Account, InventoryItem, BusinessObject (Customer, Supplier, Employee,...), có thể theo một số điều kiện liên quan như (ByWarehouseID, By....)

Tùy từng tính chất đối tượng mà ta có thể sử dụng (+) hay (-) trong công thức getBalance ở trên. (thêm parameters cho các methods nói trên)
 
Lần chỉnh sửa cuối:
Hôm nay mới thấy có bác Duyệt đọc món này và ủng hộ em :D. Chắc là do em lúc nào cũng nhắc tới món SAP của bác. Vả lại, do em viết tắt nhiều quá nên ko được phù hợp với các độc giả của diễn đàn cho lắm (mặc dù em đã phải edit lại tới 5 lần).

Bác Duyệt thử làm món này trong phần mềm quản lý kho của bác đi. Theo em đó là 1 cách khá nhanh đấy. Đặc biệt nếu các tables mà bác đều link với nhau qua ID có kiểu Long thì phải nói là cực nhanh. KH của em 1 ngày bán 1200 chứng từ bán lẻ mà vẫn tính số dư theo thời điểm tức thì ngay trên chứng từ đấy (quẹt cái ra ngay).
 
Lần chỉnh sửa cuối:
smbsolutions đã viết:
Hôm nay mới thấy có bác Duyệt đọc món này và ủng hộ em :D. Chắc là do em lúc nào cũng nhắc tới món SAP của bác. Vả lại, do em viết tắt nhiều quá nên ko được phù hợp với các độc giả của diễn đàn cho lắm (mặc dù em đã phải edit lại tới 5 lần).

Bác Duyệt thử làm món này trong phần mềm quản lý kho của bác đi. Theo em đó là 1 cách khá nhanh đấy. Đặc biệt nếu các tables mà bác đều link với nhau qua ID có kiểu Long thì phải nói là cực nhanh. KH của em 1 ngày bán 1200 chứng từ bán lẻ mà vẫn tính số dư theo thời điểm tức thì ngay trên chứng từ đấy (quẹt cái ra ngay).

Không phải là không ủng hộ bác. Chẳng qua là đọc thì hiểu, về vấn đề quản lý cũng thừa hiểu, tuy nhiên trình độ của tụi em lại chưa thể làm như thế được.
Vậy nên đành đứng ở xa gạt nước mắt mà nhìn thôi!!

Híc híc!!

Thân!
 
smbsolutions đã viết:
Bác Duyệt thử làm món này trong phần mềm quản lý kho của bác đi. Theo em đó là 1 cách khá nhanh đấy. Đặc biệt nếu các tables mà bác đều link với nhau qua ID có kiểu Long thì phải nói là cực nhanh. KH của em 1 ngày bán 1200 chứng từ bán lẻ mà vẫn tính số dư theo thời điểm tức thì ngay trên chứng từ đấy (quẹt cái ra ngay).
Đọc cái của smbsolutions thì tuyệt rồi, nhưng khổ nổi cũng phải nghiền ngẫm nhiều &&&%$R

Cái vụ này, smbsolutions nói sơ sơ, không có ví dụ thì mình cũng phải bó tay. Vì mình tự học mà.
Không biết chừng nào mình mới được 1/4 của smbsolutions. --=--

Lê Văn Duyệt
 
Mình thấy chương trình rất tuyệt giao diện Ok, còn một số tính năng đang hoàn thiện như chưa Xóa , Sữa mã ....
Hy vọng các bạn hoàn thiện sớm để chúng ta cùng nghiên cứu .
Với lại chương trình post lên để tham khảo các bạn nên đưa dữ liệu ít thôi
bạn đưa dữ liệu vào nhiều quá sẽ làm mọi người sẽ rối và khó khăn trong việc nghiên cứu.
Mình mới tham gia forum nên kinh nghiệm còn ít hy vọng học hỏi thêm từ các bạn. :P
 
Mình thấy khi nhập - xuất không nhập được số lượng 0,5 chẳng hạn... C
 
phần mềm quản lý kho

chào các bạn
cho mình hỏi phần mềm này xóa dữ liệu bằng cách nào?vì công ty mình sử dụng mặt hàng khác, vật tư khác?
cảm ơn các bạn và người đã viết ra phần mềm này, và các bạn bổ sung rất nhiều
 
không biết tác giả còn mặn mà với PM này không?
 
Chủ thớt đâu rồi nhỉ, mình cũng đang cần phần mềm quản lý kho vật tư nhưng không tìm được. Kho của mình có khoảng 1500 loại mặt hàng, không thể theo dõi được.
chủ thớt có thẻ xây dựng giúp mình phần mềm quản lý được không

Cam ơn
 
Lần chỉnh sửa cuối:
Mình làm bên nội thất.Muốn up hình ảnh của sản phẩm , hay nói cách khác là quản lý sản phẩm bằng hình ảnh.Bạn có cách nào ko?
 
Mình làm bên nội thất.Muốn up hình ảnh của sản phẩm , hay nói cách khác là quản lý sản phẩm bằng hình ảnh.Bạn có cách nào ko?

Bạn muốn up hình ảnh lên đâu? Nếu quản lý hình ảnh thì mình
nghĩ chia theo đầu mục của sản phẩm thì sẽ dễ quản lý hơn
 
tài về xem thế nào, ai dè chẳng thấy gi cả, thế may bực
 
xin các ace cho mình hỏi làm sao mà xuất số lượng lớn trong quản lý kho vật tư
vd: tồn 5.000 khi xuất 2.000 mà lại xuất 5.000 luôn
các bạn ơi giúp mình với
 
Lần chỉnh sửa cuối:
Nếu có chương trình quản lý khách hàng thì chia sẻ em với :(
 
Có điều kiện về ngày mà, làm theo cách của Bác Tuân, số tồn đầu năm đưa vào trong sh Data, với ngày là 31/12/2006 và số CT là PN0000
Với lại phần số tồn đầu năm nên đưa vào 1 sh TonKhoDauKy thì hay hơn. Tính tồn theo hàng tháng.
Ngày....SoPhieu....MaPT...SL...GT
chào bạn đề tài này lâu rồi tuy nhiên mình mới đọc, bạn cho mình hỏi, nếu như muốn in lại số phiếu xuất hoặc nhập thì làm sao để in vậy trong file chưa có chức năng này bạn có thể viết thêm phần này được ko?
cám ơn
 
khi vào bảng tinh e thi bảo đăng nhập u va pa là sao vậy anh vũ ngọc?
 
Chào các anh
Hiện tại file này đang dùng lỗi , không nhập thêm được cho những data tiếp theo
vậy anh chị nào có thể fix thêm một số vấn đề nữa là file hoàn thiện

thanks các anh
 

File đính kèm

Gửi lên đây chia sẻ với các bạn CHƯƠNG TRÌNH QUẢN LÝ KHO VẬT TƯ (PHỤ TÙNG)

I- LỜI CẢM ƠN !

Trước hết tôi xin được trân trọng cảm ơn những người bạn đã rất rất nhiệt tình giúp đỡ tôi trong quá trình thực hiện chương trình này, xin gửi lời cảm ơn đến:
- Mr. Okebab (Mr. Hiếu)
- Anhphuong (Anh Phạm Xuân Trường)
- Anh ThuNghi
- SoiBien (Anh Quốc Anh)
Trong chương trình này có sử dụng một số đọan Code có trên diễn đàn GPE.


II- SỬ DỤNG CHƯƠNG TRÌNH:

1/- Setup chế độ cho Excel:
Mở Excel -> Chọn Tools -> Chọn Macros -> Chọn Security -> Chọn Medium

2/- Mở File QUẢN LÝ KHO PHỤ TÙNG (VẬT TƯ) chọn chế độ Enable Macros.

3/- Đọc kỹ hướng dẫn sử dụng, trước khi dùng.
(Nếu có có vấn đề vui lòng liên hệ: Mr. Vũ Ngọc - 0903744734)



III/- NHỮNG ĐIỀM CẦN HÒAN THIỆN:

Tuy đã rất cố gắng nhưng chắc chắn chương trình vẫn còn nhiều thiếu sót. Một lần nữa tôi rất mong tiếp tục nhận được sự trợ giúp của các bạn để hòan thiện cho những nội dung sau:

1- Thiết lập code sao cho khi mở File sẽ tự động bỏ qua bước chọn Enable macros và vào thẳng giao diện Menu chính của chương trình / hoặc người dùng chỉ có thể chọn được chế độ Enable Macros (Tránh trường hợp người dùng vô tình hoặc cố ý chọn chế độ Disable Macros).

2- Ở Form Giấy Đề Nghị:
- Khi ta nhập liệu xong một hóa đơn / chứng từ và kết thúc bằng nút CẬP NHẬP. Lúc này dữ liệu đã được ghi vào DATA, chúng ta có thể nhìn thấy dữ liệu trong List Data Tổng Hợp Các Giấy Đề Nghị (Ở Form Nhập Liệu Giấy Đề Nghị).

- Làm sao để khi ta gõ một Số Chứng Từ nào đó đã có trong List Data Tổng Hợp Các Giấy Đề Nghị vào trong Ô Textbox Số Chứng Từ tại Form Nhập Liệu Giấy Đề Nghị (hoặc ta chọn một dòng dữ liệu nào đó trong List Data Tổng Hợp Các Giấy Đề Nghị) thì dữ liệu sẽ hiện ngược lên List Ghi Tạm và các ô Textbox, Combobox tương ứng trên form này để chúng ta sửa được dữ liệu sau đó bấm Nút Sửa để cập nhật lại những dữ liệu đã được sửa vào Data GiayDeNghi.

3- Form DANH MỤC, tạo chức năng cho các nút: Thêm mới, Sửa, Xóa.

4- Và các vấn đề khác cần sửa đổi / cải tiến cho tốt hơn (theo ý mọi người).

Đây là phần mềm chia sẻ, chúng ta hãy cùng nhau mỗi người một tay, làm cho nó hòan thiện hơn để có một PM ứng dụng hòan chỉnh từ Excel góp vào thư viện của GPE.

Mong sớm nhận được sự đóng góp của tất cả các bạn cho chương trình này !

TRÂN TRỌNG CẢM ƠN TẤT CẢ CÁC BẠN VÀ GPE !

Trình độ vẫn còn non. Chưa rành xử lý trong thực tế. Cụ thể File đã mở rồi và người dùng đã nhập liệu rồi. Chưa kịp Save, Người tiếp tục mở lại tiếp 1 lần nửa từ File ở màn hình Desktop nếu chọn YES coi như không lưu gì hết.

1593006855490.png
 

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

Back
Top Bottom