Thiết lập file excel lưu trữ lịch sử (1 người xem)

Liên hệ QC

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

CaoNgan99

Thành viên mới
Tham gia
19/12/21
Bài viết
28
Được thích
1
Giới tính
Nữ
Em chào các anh chị !
hiện em có một file em đang xây dựng để lưu trữ lịch sử các đơn hàng.
Tại sheet historys
khi nhấn vào nút "refresh All" sẽ lấy toàn bộ dữ liệu ở sheet summary đổ sang sheet historys từ A2 đến Y, mỗi khi có dữ liệu mới từ sheet summary thì sẽ được thêm nối tiếp vào sheet historys.

từ cột Z đến AQ là cập nhật từ các sheet khác,
Điều cập nhật là nếu tìm thấy dữ liệu tại cột A sheet Historys ở các sheet còn lại (MATER_ITEM, SHIPOUT, ORDER_SCAN, BY_DATE, KITTING, MATERIAL_SHORTAGE, PRINT_STAGE, CUT_STAGE, BCNK, SOL_CANCEL) thì trả về các vùng tương ứng, mỗi lần các sheet khác thay đổi nội dung thì các vùng bên sheet History cũng được cập nhật theo
và nếu dữ liệu ở các sheet summary hay các sheet khác bị mất thì dữ liệu trong sheet historys không bị mất đi

code thì hiện tại em đã nhặt nhạnh khắp nơi để lắp ghép chỉ còn duy nhất một sheet MATER_ITEM là em không thể nào lắp ghép được vì tham số nằm ở cột L chứ không phải cột A nữa, em đã thử rất nhiều lần nó báo lỗi,

Mã:
For t = 1 To UBound(Sarr_Item)
  Tmp_Item = Sarr_Item(t, 1)
  Dic.Add (Tmp_Item), t
  'If DR(i, 19) <> "AWAITING_SHIPPING" Or DR(i, 19) <> "AWAITING_FULFILLMENT" Then 'co the tuy chinh
    Dic95.Add (Tmp_Item), t
    If DR_Item(t, 8) = "AWAITING_FULFILLMENT" Or DR_Item(t, 8) = "AWAITING_SHIPPING" Or DR_Item(t, 8) = "PRODUCTION_OPEN" Or DR_Item(i, 8) = "EXTERNAL_REQ_OPEN" Or DR_Item(t, 8) = "PO_PARTIAL" Or DR_Item(t, 8) = "PO_OPEN" Or DR_Item(t, 8) = "BOOKED" Or DR_Item(t, 8) = "SUPPLY_ELIGIBLE" Or DR_Item(t, 8) = "ENTERED" Then Dic35.Add (Tmp_Item), t
  'End If
Next t

nên em đã đặt công thức vlookup tại cột AM đến AO sheet historys để anh chị xem và sửa giúp em với, vì bình thường em có thể vlookup nhưng dữ liệu có lúc lên đến 60000 dòng chạy rất chậm.

em cám ơn trước ạ
 

File đính kèm

Lần chỉnh sửa cuối:
Em chào các anh chị !
hiện em có một file em đang xây dựng để lưu trữ lịch sử các đơn hàng.
Tại sheet historys
khi nhấn vào nút "refresh All" sẽ lấy toàn bộ dữ liệu ở sheet summary đổ sang sheet historys từ A2 đến Y, mỗi khi có dữ liệu mới từ sheet summary thì sẽ được thêm nối tiếp vào sheet historys.

từ cột Z đến AQ là cập nhật từ các sheet khác,
Điều cập nhật là nếu tìm thấy dữ liệu tại cột A sheet Historys ở các sheet còn lại (MATER_ITEM, SHIPOUT, ORDER_SCAN, BY_DATE, KITTING, MATERIAL_SHORTAGE, PRINT_STAGE, CUT_STAGE, BCNK, SOL_CANCEL) thì trả về các vùng tương ứng, mỗi lần các sheet khác thay đổi nội dung thì các vùng bên sheet History cũng được cập nhật theo
và nếu dữ liệu ở các sheet summary hay các sheet khác bị mất thì dữ liệu trong sheet historys không bị mất đi

code thì hiện tại em đã nhặt nhạnh khắp nơi để lắp ghép chỉ còn duy nhất một sheet MATER_ITEM là em không thể nào lắp ghép được vì tham số nằm ở cột L chứ không phải cột A nữa, em đã thử rất nhiều lần nó báo lỗi,

Mã:
For t = 1 To UBound(Sarr_Item)
  Tmp_Item = Sarr_Item(t, 1)
  Dic.Add (Tmp_Item), t
  'If DR(i, 19) <> "AWAITING_SHIPPING" Or DR(i, 19) <> "AWAITING_FULFILLMENT" Then 'co the tuy chinh
    Dic95.Add (Tmp_Item), t
    If DR_Item(t, 8) = "AWAITING_FULFILLMENT" Or DR_Item(t, 8) = "AWAITING_SHIPPING" Or DR_Item(t, 8) = "PRODUCTION_OPEN" Or DR_Item(i, 8) = "EXTERNAL_REQ_OPEN" Or DR_Item(t, 8) = "PO_PARTIAL" Or DR_Item(t, 8) = "PO_OPEN" Or DR_Item(t, 8) = "BOOKED" Or DR_Item(t, 8) = "SUPPLY_ELIGIBLE" Or DR_Item(t, 8) = "ENTERED" Then Dic35.Add (Tmp_Item), t
  'End If
Next t

nên em đã đặt công thức vlookup tại cột AM đến AO sheet historys để anh chị xem và sửa giúp em với, vì bình thường em có thể vlookup nhưng dữ liệu có lúc lên đến 60000 dòng chạy rất chậm.

em cám ơn trước ạ
Code trong Sub History của bạn khó hiểu quá.
Tôi đọc và tự hỏi sao là sao bạn không gán Từ A2:Y... của sh SUMARY thành một Array Tạm đặt là Arr và chạy vòng lặp từ 1 đến Ubound(Arr). trong đó lấy các phần tử của cột nào làm dic thì add vào. và thực hiện các tác vụ tiếp theo.....

" từ cột Z đến AQ là cập nhật từ các sheet khác," thì cập nhật theo điều kiện nào?
"Điều cập nhật là nếu tìm thấy dữ liệu tại cột A sheet Historys " ở cột nào? của " các sheet còn lại (MATER_ITEM, SHIPOUT, ORDER_SCAN, BY_DATE, KITTING, MATERIAL_SHORTAGE, PRINT_STAGE, CUT_STAGE, BCNK, SOL_CANCEL) thì trả về các vùng tương ứng" là vùng nào?" , mỗi lần các sheet khác thay đổi nội dung thì các vùng bên sheet History cũng được cập nhật theo.."
 
Upvote 0
Code trong Sub History của bạn khó hiểu quá.
Tôi đọc và tự hỏi sao là sao bạn không gán Từ A2:Y... của sh SUMARY thành một Array Tạm đặt là Arr và chạy vòng lặp từ 1 đến Ubound(Arr). trong đó lấy các phần tử của cột nào làm dic thì add vào. và thực hiện các tác vụ tiếp theo.....

" từ cột Z đến AQ là cập nhật từ các sheet khác," thì cập nhật theo điều kiện nào?
"Điều cập nhật là nếu tìm thấy dữ liệu tại cột A sheet Historys " ở cột nào? của " các sheet còn lại (MATER_ITEM, SHIPOUT, ORDER_SCAN, BY_DATE, KITTING, MATERIAL_SHORTAGE, PRINT_STAGE, CUT_STAGE, BCNK, SOL_CANCEL) thì trả về các vùng tương ứng" là vùng nào?" , mỗi lần các sheet khác thay đổi nội dung thì các vùng bên sheet History cũng được cập nhật theo.."
Dạ là do em lấy code từ trên diễn đàn giaiphapexcel để lắp ghép thôi ạ, chứ em hoàn toàn không có khả năng code.
nên mới thành ra như vậy, em xin trả lời từng ý của anh nhé nhé để a dễ hiểu

" từ cột Z đến AQ là cập nhật từ các sheet khác," thì cập nhật theo điều kiện nào? -> theo điều kiện lấy cột A sheet Historys làm tham số.

'' Điều cập nhật là nếu tìm thấy dữ liệu tại cột A sheet Historys ở cột nào? của các sheet còn lại (MATER_ITEM, SHIPOUT, ORDER_SCAN, BY_DATE, KITTING, MATERIAL_SHORTAGE, PRINT_STAGE, CUT_STAGE, BCNK, SOL_CANCEL)
-> SHIPOUT(Cột A), ORDER_SCAN(cột A), BY_DATE(Cột A), KITTING(Cột A), MATERIAL_SHORTAGE(Cột B), PRINT_STAGE(Cột A), CUT_STAGE(Cột A), BCNK(Cột B), SOL_CANCEL(Cột A),


" là vùng nào?
-Nếu tìm thấy cột A sheet historys ở cột A bên sheet SHIPOUT thì lấy dữ liệu ở các cột B, C trả về vùng
Z, AA sheet historys


-Nếu tìm thấy cột A sheet historys ở cột A bên sheet ORDER_SCAN thì lấy dữ liệu ở cột C trả về vùng
AB sheet historys


-Nếu tìm thấy cột A sheet historys ở cột A bên sheet BY_DATE thì lấy dữ liệu ở cột B trả về vùng
AP sheet historys


-Nếu tìm thấy cột A sheet historys ở cột A bên sheet KITTING thì lấy dữ liệu ở cột B trả về vùng
AC sheet historys


-Nếu tìm thấy cột A sheet historys ở cột B bên sheet MATERIAL_SHORTAGE thì lấy dữ liệu ở cột N trả về vùng
AD sheet historys


-Nếu tìm thấy cột A sheet historys ở cột A bên sheet PRINT_STAGE thì lấy dữ liệu ở các cột B C D trả về vùng
AE, AF, AG sheet historys


-Nếu tìm thấy cột A sheet historys ở cột A bên sheet CUT_STAGE thì lấy dữ liệu ở các cột B C D trả về vùng
AH, AI, AJ sheet historys


-Nếu tìm thấy cột A sheet historys ở cột B bên sheet BCNK thì lấy dữ liệu ở các cột C D trả về vùng
AK, AL sheet historys


-Nếu tìm thấy cột A sheet historys ở cột A bên sheet SOL_CANCEL thì lấy dữ liệu ở cột B trả về vùng
AQ sheet historys


riêng sheet MATER_ITEM thì điều kiện khác một chút là nếu tìm thấy cột L sheet historys ở cột B bên sheet MATER_ITEM thì lấy dữ liệu ở các cột E F G trả về vùng AM, AN, AO sheet historys

các cột B,C,D,E và S của sheet historys sẽ được cập nhật từ sheet summary dựa theo điều kiện cả 2 sheet đều có cột A làm khóa chính, tức là nếu tìm thấy cột A của sheet historys bên cột A của sheet summary thì lấy dữ liệu của các cột B,C,D,E và S cập nhật sang các cột B,C,D,E và S của sheet historys.
 
Lần chỉnh sửa cuối:
Upvote 0
Đừng bắt người khác phải dò code của mình để đoán ra ý của mình. Đoán ý trên cơ sở code rất cực khi không có chú thích. Và nếu code sai hoặc không chuẩn thì nhiều khi từ code KHÔNG THỂ ĐOÁN được ý. Ý chỉ có thể đoán được từ code đúng. Ngoài ra không phải ai cũng có hứng dò code của người khác. Và cái quan trọng nhất, tại sao tôi phải bỏ công ra đoán trong khi vấn đề của người ta, người ta có thể mô tả nhưng không mô tả?
khi nhấn vào nút "refresh All" sẽ lấy toàn bộ dữ liệu ở sheet summary đổ sang sheet historys từ A2 đến Y, mỗi khi có dữ liệu mới từ sheet summary thì sẽ được thêm nối tiếp vào sheet historys.
Thế nào là "dữ liệu mới"? Vd. dòng dữ liệu trong SUMMARY mà A & B & C & ... & Z KHÔNG BẰNG bất cứ A & B & C & ... & Z trong HISTORYS thì là DỮ LIỆU MỚI? Tôi biết là không phải thế. Vậy phải thế là thế nào? Khái niệm "dữ liệu mới" thế nào?
Điều cập nhật là nếu tìm thấy dữ liệu tại cột A sheet Historys ở các sheet còn lại (MATER_ITEM, SHIPOUT, ORDER_SCAN, BY_DATE, KITTING, MATERIAL_SHORTAGE, PRINT_STAGE, CUT_STAGE, BCNK, SOL_CANCEL) thì trả về các vùng tương ứng

Tôi hiểu là khi duyệt SUMMARY thì:
- giá trị cần tìm: từng giá trị trong cột A (?) của SUMMARY
- nơi cần tìm: cột A (?) của HISTORYS

Tôi hiểu như trên là đúng?

Khi duyệt MATER_ITEM, SHIPOUT, ... thì ngược lại;
- giá trị cần tìm: từng giá trị trong cột "A" hoặc "L" của sheet HISTORYS
- nơi cần tìm: cột "A" hoặc "B" của sheet ĐANG DUYỆT

Tôi hiểu như trên là đúng?

Nếu tôi hiểu chưa đúng thì đúng là phải thế nào?

Ngoài ra thứ tự thao tác rất quan trọng. Ở trên theo tôi hiểu thì khi duyệt SUMMARY thì nếu có "dữ liệu mới" thì THÊM vào dòng cuối của HISTORYS. Vậy thì nếu duyệt SUMMARY trước khi duyệt MATER_ITEM, SHIPOUT, ... sẽ cho kết quả khác với duyệt MATER_ITEM, SHIPOUT, ... trước khi duyệt SUMMARY.

Tóm lại là mô tả chính xác THỨ TỰ thao tác. Và:
- khi duyệt SUMMARY thì lấy gì, từ đâu, để tìm ở đâu. Khi thỏa điều kiện gì thì lấy gì, từ đâu, để nhập vào đâu.
- khi duyệt MATER_ITEM, SHIPOUT, ... thì lấy gì, từ đâu, để tìm ở đâu. Khi thỏa điều kiện gì thì lấy gì, từ đâu, để nhập vào đâu.
--------------
Sau khi đọc ở bài #3
các cột B,C,D,E và S của sheet historys sẽ được cập nhật từ sheet summary dựa theo điều kiện cả 2 sheet đều có cột A làm khóa chính, tức là nếu tìm thấy cột A của sheet historys bên cột A của sheet summary thì lấy dữ liệu của các cột B,C,D,E và S cập nhật sang các cột B,C,D,E và S của sheet historys.
thì tôi thử đoán như sau:
1. Thứ tự thao tác: trước tiên duyệt SUMMARY, tiếp theo là các sheet được liệt kê trong bài #1.

2. Duyệt SUMMARY.
Dò từng SOL trong cột A của SUMMARY trong cột A của HISTORYS. Tôi cho là khi không tìm thấy SOL hiện hành thì dòng chứa SOL đó là "Dữ liệu mới". Nhưng tôi không dám chắc vì tôi không hiểu tại sao trong code lại có kiểm tra xem cột S của HISTORYS có là AWAITING_SHIPPING, ... hay không. Tôi không theo dõi kỹ vì mệt lắm.
Nếu tìm thấy SOL trong HISTORYS thì lấy B, C, D, E và S từ SUMMARY sang HISTORYS. Nếu không tìm thấy SOL (dữ liệu mới?) thì lấy toàn bộ dòng chứa SOL đó từ SUMMARY sang thêm vào dòng cuối của HISTORYS.

Tôi hiểu như trên là đúng? Hãy phát biểu rõ, thế nào là "dữ liệu mới".

3. Khi duyệt các sheet MATER_ITEM, SHIPOUT, ... thì như bài #3: khi tìm thấy thì lấy từ các sheet đang duyệt sang HISTORYS. Thế nếu không tìm thấy thì sao? Thì KHÔNG LÀM GÌ? Mọi cái nên nói huỵch toẹt ra, đừng bắt người khác phải đoán ý.
 
Upvote 0
Đừng bắt người khác phải dò code của mình để đoán ra ý của mình. Đoán ý trên cơ sở code rất cực khi không có chú thích. Và nếu code sai hoặc không chuẩn thì nhiều khi từ code KHÔNG THỂ ĐOÁN được ý. Ý chỉ có thể đoán được từ code đúng. Ngoài ra không phải ai cũng có hứng dò code của người khác. Và cái quan trọng nhất, tại sao tôi phải bỏ công ra đoán trong khi vấn đề của người ta, người ta có thể mô tả nhưng không mô tả?

Thế nào là "dữ liệu mới"? Vd. dòng dữ liệu trong SUMMARY mà A & B & C & ... & Z KHÔNG BẰNG bất cứ A & B & C & ... & Z trong HISTORYS thì là DỮ LIỆU MỚI? Tôi biết là không phải thế. Vậy phải thế là thế nào? Khái niệm "dữ liệu mới" thế nào?


Tôi hiểu là khi duyệt SUMMARY thì:
- giá trị cần tìm: từng giá trị trong cột A (?) của SUMMARY
- nơi cần tìm: cột A (?) của HISTORYS

Tôi hiểu như trên là đúng?

Khi duyệt MATER_ITEM, SHIPOUT, ... thì ngược lại;
- giá trị cần tìm: từng giá trị trong cột "A" hoặc "L" của sheet HISTORYS
- nơi cần tìm: cột "A" hoặc "B" của sheet ĐANG DUYỆT

Tôi hiểu như trên là đúng?

Nếu tôi hiểu chưa đúng thì đúng là phải thế nào?

Ngoài ra thứ tự thao tác rất quan trọng. Ở trên theo tôi hiểu thì khi duyệt SUMMARY thì nếu có "dữ liệu mới" thì THÊM vào dòng cuối của HISTORYS. Vậy thì nếu duyệt SUMMARY trước khi duyệt MATER_ITEM, SHIPOUT, ... sẽ cho kết quả khác với duyệt MATER_ITEM, SHIPOUT, ... trước khi duyệt SUMMARY.

Tóm lại là mô tả chính xác THỨ TỰ thao tác. Và:
- khi duyệt SUMMARY thì lấy gì, từ đâu, để tìm ở đâu. Khi thỏa điều kiện gì thì lấy gì, từ đâu, để nhập vào đâu.
- khi duyệt MATER_ITEM, SHIPOUT, ... thì lấy gì, từ đâu, để tìm ở đâu. Khi thỏa điều kiện gì thì lấy gì, từ đâu, để nhập vào đâu.
--------------
Sau khi đọc ở bài #3

thì tôi thử đoán như sau:
1. Thứ tự thao tác: trước tiên duyệt SUMMARY, tiếp theo là các sheet được liệt kê trong bài #1.

2. Duyệt SUMMARY.
Dò từng SOL trong cột A của SUMMARY trong cột A của HISTORYS. Tôi cho là khi không tìm thấy SOL hiện hành thì dòng chứa SOL đó là "Dữ liệu mới". Nhưng tôi không dám chắc vì tôi không hiểu tại sao trong code lại có kiểm tra xem cột S của HISTORYS có là AWAITING_SHIPPING, ... hay không. Tôi không theo dõi kỹ vì mệt lắm.
Nếu tìm thấy SOL trong HISTORYS thì lấy B, C, D, E và S từ SUMMARY sang HISTORYS. Nếu không tìm thấy SOL (dữ liệu mới?) thì lấy toàn bộ dòng chứa SOL đó từ SUMMARY sang thêm vào dòng cuối của HISTORYS.

Tôi hiểu như trên là đúng? Hãy phát biểu rõ, thế nào là "dữ liệu mới".

3. Khi duyệt các sheet MATER_ITEM, SHIPOUT, ... thì như bài #3: khi tìm thấy thì lấy từ các sheet đang duyệt sang HISTORYS. Thế nếu không tìm thấy thì sao? Thì KHÔNG LÀM GÌ? Mọi cái nên nói huỵch toẹt ra, đừng bắt người khác phải đoán ý.
Dạ em xin lỗi, em không cố ý gây khó hiểu vậy, em xin giải thích các câu hỏi của anh

Thế nào là "dữ liệu mới"? Vd. dòng dữ liệu trong SUMMARY mà A & B & C & ... & Z KHÔNG BẰNG bất cứ A & B & C & ... & Y trong HISTORYS thì là DỮ LIỆU MỚI?-> chính xác anh nhé, dữ liệu mới là dữ liệu được thêm vào sheet summary nhưng chưa có bên sheet historys thông qua cột A là khóa chính

Tôi hiểu là khi duyệt SUMMARY thì:
- giá trị cần tìm: từng giá trị trong cột A (?) của SUMMARY
- nơi cần tìm: cột A (?) của HISTORYS

Tôi hiểu như trên là đúng?-> chính xác anh nhé

Khi duyệt MATER_ITEM, SHIPOUT, ... thì ngược lại;
- giá trị cần tìm: từng giá trị trong cột "A" hoặc "L" của sheet HISTORYS
- nơi cần tìm: cột "A" hoặc "B" của sheet ĐANG DUYỆT

Tôi hiểu như trên là đúng?-> chính xác ạ

Ngoài ra thứ tự thao tác rất quan trọng. Ở trên theo tôi hiểu thì khi duyệt SUMMARY thì nếu có "dữ liệu mới" thì THÊM vào dòng cuối của HISTORYS. Vậy thì nếu duyệt SUMMARY trước khi duyệt MATER_ITEM, SHIPOUT, ... sẽ cho kết quả khác với duyệt MATER_ITEM, SHIPOUT, ... trước khi duyệt SUMMARY. -> chính xác ạ

các cột B,C,D,E và S của sheet historys sẽ được cập nhật từ sheet summary dựa theo điều kiện cả 2 sheet đều có cột A làm khóa chính, tức là nếu tìm thấy cột A của sheet historys bên cột A của sheet summary thì lấy dữ liệu của các cột B,C,D,E và S cập nhật sang các cột B,C,D,E và S của sheet historys.

1. Thứ tự thao tác: trước tiên duyệt SUMMARY, tiếp theo là các sheet được liệt kê trong bài #1.

2. Duyệt SUMMARY.
Dò từng SOL trong cột A của SUMMARY trong cột A của HISTORYS. Tôi cho là khi không tìm thấy SOL hiện hành thì dòng chứa SOL đó là "Dữ liệu mới". Nhưng tôi không dám chắc vì tôi không hiểu tại sao trong code lại có kiểm tra xem cột S của HISTORYS có là AWAITING_SHIPPING, ... hay không. Tôi không theo dõi kỹ vì mệt lắm. -> cái này là do code khi em nhặt họ đã để theo trạng thái, em không biết code lại nên em lấy về và hợp thức hóa bằng cách thêm điều kiện của cột S vào để quét toàn bộ dữ liệu thôi ah, chứ còn chứ còn dữ liệu mới như em đã trình bày là dựa vào khóa chính ở cột A giữa 2 sheet summary và historys để lấy ra toàn bộ các dòng có ở sheet summary nhưng không có ở historys thì được gọi là dữ liệu mới để thêm nối tiếp vào sheet historys

3. Khi duyệt các sheet MATER_ITEM, SHIPOUT, ... thì như bài #3: khi tìm thấy thì lấy từ các sheet đang duyệt sang HISTORYS. Thế nếu không tìm thấy thì sao? Thì KHÔNG LÀM GÌ? Mọi cái nên nói huỵch toẹt ra, đừng bắt người khác phải đoán ý. -> nếu không tìm thấy thì không cần làm gì anh nhé


tương tự các cột B,C,D,E và S của sheet historys sẽ được cập nhật từ sheet summary dựa theo điều kiện cả 2 sheet đều có cột A làm khóa chính, tức là nếu tìm thấy cột A của sheet historys bên cột A của sheet summary thì lấy dữ liệu của các cột B,C,D,E và S cập nhật sang các cột B,C,D,E và S của sheet historys.

Em xin tổng hợp lại thứ tự nhé

1) lấy toàn bộ dữ liệu mới từ sheet summary từ cột A đến Y sang sheet historys
2) cập nhật B,C,D,E và S của sheet historys theo sheet sheet summary dựa trên cột A làm khóa chính của 2 sheet

3) cập nhật dữ liệu từ các sheet MATER_ITEM, SHIPOUT, ORDER_SCAN, BY_DATE, KITTING, MATERIAL_SHORTAGE, PRINT_STAGE, CUT_STAGE, BCNK, SOL_CANCEL vào sheet historys.
4) Nếu dữ liệu ở sheet summary và các sheet khác bị mất thì dữ liệu trong sheet historys vẫn được bảo toàn
 
Upvote 0
Thế nào là "dữ liệu mới"? Vd. dòng dữ liệu trong SUMMARY mà A & B & C & ... & Z KHÔNG BẰNG bất cứ A & B & C & ... & Y trong HISTORYS thì là DỮ LIỆU MỚI?-> chính xác anh nhé, dữ liệu mới là dữ liệu được thêm vào sheet summary nhưng chưa có bên sheet historys thông qua cột A là khóa chính
Thông qua là cái khỉ gì. Tôi đang nói tới:
a. hoặc mới là A & B & ... & Z mới
b. hoặc mới là A mới

Vd. Bên HISTORYS có A = 12345, B = "blala, C = "hic hic", Bên SUMMARY có A = 12345, B = "blala, C = "he he". Vậy đó có là DỮ LIỆU MỚI không? Theo a. thì là DỮ LIỆU MỚI do "12345blalahe he" <> "12345blalahic hic", còn theo b. thì không là dữ liệu mới vì 12345 (SUMMARY) = 12345 (HISTORYS).

Hoặc mới là khi ít nhất 1 cột trong A:Z là mới, hoặc mới là khi có A mới. Làm gì có kiểu: mới khi ít nhất 1 cột trong A:Z là mới THÔNG QUA cột A.

Thôi tôi không đọc tiếp nữa. Tôi sẽ làm theo một giả thiết nhất định.

1. Trước hết duyệt SUMMARY. kiểm tra từng SOL có trong cột A của HISTORYS không. Nếu có rồi thì cập nhật B,C,D,E và S của sheet historys. Nếu chưa có SOL đang xét trong HISTORYS!A thì toàn bộ dòng có SOL đó từ A tới Y được nhập vào dòng cuối bên HISTORYS.

2. Sau khi duyệt SUMMARY thì duyệt các sheet khác theo mô tả ở bài #3.

3. Tôi không dò code của bạn, mệt lắm. Tôi thử đập đi xây mới. Tôi viết lại Sub History

4. Có nhiều cái bạn phải kiểm tra lại.

1. Trong SUMMARY dạng dữ liệu X572:X573, Y572:Y573 (đều là các số) không ăn nhập gì với dạng của cột X và Y (dạng text). Tương tự Y2470, M174:M185, và nhiều khoảng nữa trong cột M. Vì thế sang HISTORYS cũng kỳ cục - X566:Y567 và Y2464, và M173:M184 và nhiều khoảng nữa trong cột M

2. Trong SUMMARY chắc chắn cột C, D và E không có ngày tháng chuẩn, và chúng được coi là có dạng MM/dd/yyyy. Vì thế khi chạy trên máy bạn thì có thể sẽ có vd. HISTORYS!C2 = 06 tháng 10 năm 2021, nhưng khi chạy code ở máy tôi sẽ có HISTORYS!C2 = 10 tháng 06 năm 2021. Nguyên nhân là do SUMMARY!C2 không là ngày tháng chuẩn - khi mở trên máy tôi C2 được căn trái. Trên máy tôi thì sau khi chạy code trong HISTORYS!C, D, E hoặc sẽ có ngày tháng chuẩn nhưng ngày tháng sẽ bị đổi chỗ (bên SUMMARY có số đầu < 13), hoặc ngày tháng "nhái" (bên SUMMARY số đầu > 12), chúng được bê y nguyên từ SUMMARY sang HISTORYS .

Tóm lại nếu nói về dữ liệu nguồn trong SUMMARY thì phải kiểm tra lại cột C, D, E (ngày tháng không chuẩn), và cột M, X, Y - định dạng ô không phù hợp, dạng dữ liệu không ăn nhập gì với dạng của cột, tức khác với dạng của các dữ liệu khác trong cùng cột.

Tất nhiên phải kiểm tra xem kết quả code có đúng ý không.
 

File đính kèm

Upvote 0
Thông qua là cái khỉ gì. Tôi đang nói tới:
a. hoặc mới là A & B & ... & Z mới
b. hoặc mới là A mới

Vd. Bên HISTORYS có A = 12345, B = "blala, C = "hic hic", Bên SUMMARY có A = 12345, B = "blala, C = "he he". Vậy đó có là DỮ LIỆU MỚI không? Theo a. thì là DỮ LIỆU MỚI do "12345blalahe he" <> "12345blalahic hic", còn theo b. thì không là dữ liệu mới vì 12345 (SUMMARY) = 12345 (HISTORYS).

Hoặc mới là khi ít nhất 1 cột trong A:Z là mới, hoặc mới là khi có A mới. Làm gì có kiểu: mới khi ít nhất 1 cột trong A:Z là mới THÔNG QUA cột A.

Thôi tôi không đọc tiếp nữa. Tôi sẽ làm theo một giả thiết nhất định.

1. Trước hết duyệt SUMMARY. kiểm tra từng SOL có trong cột A của HISTORYS không. Nếu có rồi thì cập nhật B,C,D,E và S của sheet historys. Nếu chưa có SOL đang xét trong HISTORYS!A thì toàn bộ dòng có SOL đó từ A tới Y được nhập vào dòng cuối bên HISTORYS.

2. Sau khi duyệt SUMMARY thì duyệt các sheet khác theo mô tả ở bài #3.

3. Tôi không dò code của bạn, mệt lắm. Tôi thử đập đi xây mới. Tôi viết lại Sub History

4. Có nhiều cái bạn phải kiểm tra lại.

1. Trong SUMMARY dạng dữ liệu X572:X573, Y572:Y573 (đều là các số) không ăn nhập gì với dạng của cột X và Y (dạng text). Tương tự Y2470, M174:M185, và nhiều khoảng nữa trong cột M. Vì thế sang HISTORYS cũng kỳ cục - X566:Y567 và Y2464, và M173:M184 và nhiều khoảng nữa trong cột M

2. Trong SUMMARY chắc chắn cột C, D và E không có ngày tháng chuẩn, và chúng được coi là có dạng MM/dd/yyyy. Vì thế khi chạy trên máy bạn thì có thể sẽ có vd. HISTORYS!C2 = 06 tháng 10 năm 2021, nhưng khi chạy code ở máy tôi sẽ có HISTORYS!C2 = 10 tháng 06 năm 2021. Nguyên nhân là do SUMMARY!C2 không là ngày tháng chuẩn - khi mở trên máy tôi C2 được căn trái. Trên máy tôi thì sau khi chạy code trong HISTORYS!C, D, E hoặc sẽ có ngày tháng chuẩn nhưng ngày tháng sẽ bị đổi chỗ (bên SUMMARY có số đầu < 13), hoặc ngày tháng "nhái" (bên SUMMARY số đầu > 12), chúng được bê y nguyên từ SUMMARY sang HISTORYS .

Tóm lại nếu nói về dữ liệu nguồn trong SUMMARY thì phải kiểm tra lại cột C, D, E (ngày tháng không chuẩn), và cột M, X, Y - định dạng ô không phù hợp, dạng dữ liệu không ăn nhập gì với dạng của cột, tức khác với dạng của các dữ liệu khác trong cùng cột.

Tất nhiên phải kiểm tra xem kết quả code có đúng ý không.
Em cảm ơn anh nhé,
về phần định dạng ngày tháng thì đúng là nó đang khác định dạng, trước em cũng bị rồi và em phải đưa thêm
Sarr(k, 3) = Format(DR(i, 3), "dd/mmm/yyyy")
Sarr(k, 4) = Format(DR(i, 4), "dd/mmm/yyyy")
Sarr(k, 5) = Format(DR(i, 5), "dd/mmm/yyyy")
trong file đính kèm ở bài 1 và ăn may làm sao nó lại ra được, em có mở code của anh ra để xem có thể thêm được không nhưng không thể làm được, nên a xem sửa giúp em với, còn dữ liệu các cột X Y M, khi copy vào historys a định dạng hết sang text cũng được ạ
- Về phần dữ liệu mới mà em muốn nối tiếp sang sheet history tức là nếu phần dữ liệu từ cột A đến Y có ở sheet summary mà không có ở sheet historys thì lấy phần dữ liệu không có từ cột A đến Y đó chuyển sang thêm nối tiếp vào sheet historys, hiện tại thì em thấy nó chỉ copy nối được một số cột cho nên em mới hiểu câu hỏi của anh để giải thích thế nào là dữ liệu mới, em sợ nói không đúng lại bị mắng.
 
Upvote 0
Dạ là do em lấy code từ trên diễn đàn giaiphapexcel để lắp ghép thôi ạ, chứ em hoàn toàn không có khả năng code.
nên mới thành ra như vậy, em xin trả lời từng ý của anh nhé nhé để a dễ hiểu

" từ cột Z đến AQ là cập nhật từ các sheet khác," thì cập nhật theo điều kiện nào? -> theo điều kiện lấy cột A sheet Historys làm tham số.

'' Điều cập nhật là nếu tìm thấy dữ liệu tại cột A sheet Historys ở cột nào? của các sheet còn lại (MATER_ITEM, SHIPOUT, ORDER_SCAN, BY_DATE, KITTING, MATERIAL_SHORTAGE, PRINT_STAGE, CUT_STAGE, BCNK, SOL_CANCEL)
-> SHIPOUT(Cột A), ORDER_SCAN(cột A), BY_DATE(Cột A), KITTING(Cột A), MATERIAL_SHORTAGE(Cột B), PRINT_STAGE(Cột A), CUT_STAGE(Cột A), BCNK(Cột B), SOL_CANCEL(Cột A),


" là vùng nào?
-Nếu tìm thấy cột A sheet historys ở cột A bên sheet SHIPOUT thì lấy dữ liệu ở các cột B, C trả về vùng
Z, AA sheet historys


-Nếu tìm thấy cột A sheet historys ở cột A bên sheet ORDER_SCAN thì lấy dữ liệu ở cột C trả về vùng
AB sheet historys


-Nếu tìm thấy cột A sheet historys ở cột A bên sheet BY_DATE thì lấy dữ liệu ở cột B trả về vùng
AP sheet historys


-Nếu tìm thấy cột A sheet historys ở cột A bên sheet KITTING thì lấy dữ liệu ở cột B trả về vùng
AC sheet historys


-Nếu tìm thấy cột A sheet historys ở cột B bên sheet MATERIAL_SHORTAGE thì lấy dữ liệu ở cột N trả về vùng
AD sheet historys


-Nếu tìm thấy cột A sheet historys ở cột A bên sheet PRINT_STAGE thì lấy dữ liệu ở các cột B C D trả về vùng
AE, AF, AG sheet historys


-Nếu tìm thấy cột A sheet historys ở cột A bên sheet CUT_STAGE thì lấy dữ liệu ở các cột B C D trả về vùng
AH, AI, AJ sheet historys


-Nếu tìm thấy cột A sheet historys ở cột B bên sheet BCNK thì lấy dữ liệu ở các cột C D trả về vùng
AK, AL sheet historys


-Nếu tìm thấy cột A sheet historys ở cột A bên sheet SOL_CANCEL thì lấy dữ liệu ở cột B trả về vùng
AQ sheet historys


riêng sheet MATER_ITEM thì điều kiện khác một chút là nếu tìm thấy cột L sheet historys ở cột B bên sheet MATER_ITEM thì lấy dữ liệu ở các cột E F G trả về vùng AM, AN, AO sheet historys

các cột B,C,D,E và S của sheet historys sẽ được cập nhật từ sheet summary dựa theo điều kiện cả 2 sheet đều có cột A làm khóa chính, tức là nếu tìm thấy cột A của sheet historys bên cột A của sheet summary thì lấy dữ liệu của các cột B,C,D,E và S cập nhật sang các cột B,C,D,E và S của sheet historys.
Thêm một cách nữa cho bạn rộng đường lựa chọn.
Hãy vào Sh History(Thu) và nhấn nút để xem và kiểm tra kết quả.
Bạn hãy thử thêm dữ liệu của Sh SUMMARY và kiểm tra lại trên sh History. các sh khác cũng vậy. Tôi đã mất cả một ngày để làm chức năng này theo yêu cầu "
....mỗi lần các sheet khác thay đổi nội dung thì các vùng bên sheet History cũng được cập nhật theo
và nếu dữ liệu ở các sheet summary hay các sheet khác bị mất thì dữ liệu trong sheet historys không bị mất đi...."
này của bạn.
nhớ là kiểm tra thật kỹ. Tôi cũng chưa kiểm tra kỹ được đâu.
Các Sub History cũ của bạn tôi đã xóa bỏ và viết lại (nó chỉ cần đến khi nào bạn muốn sử dụng để Refersh toàn bộ-Dễ kiểm tra)
Xem file đính kèm.
Ngóng chờ hồi âm
 

File đính kèm

Upvote 0
Em cảm ơn anh nhé,
về phần định dạng ngày tháng thì đúng là nó đang khác định dạng, trước em cũng bị rồi và em phải đưa thêm
Sarr(k, 3) = Format(DR(i, 3), "dd/mmm/yyyy")
Sarr(k, 4) = Format(DR(i, 4), "dd/mmm/yyyy")
Sarr(k, 5) = Format(DR(i, 5), "dd/mmm/yyyy")
Tôi không bao giờ chấp nhận kiểu Format như thế. Đâu có phải trên máy nào cũng dùng "/" và ngày trước tháng. Vd. ở máy tôi là 20.12.2021. Nếu nói về ngày tháng chuẩn thì tôi khuyên là chuyển ngay dữ liệu gốc về chuẩn. Thế thôi. vd. cột SUMMARY!C. Có thể cho là dữ liệu từ cùng một nguồn nên cùng dạng. Nhìn có 23/11/2021 nên có thể cho là dữ liệu kiểu dd/MM/yyyy. Vậy thì để chuyển C về chuẩn thì: chọn tất cả dữ liệu cột C -> thẻ Data -> Text to Columns -> Next -> Next -> chọn Date -> bên cạnh chọn DMY -> nhấn Finish.
còn dữ liệu các cột X Y M, khi copy vào historys a định dạng hết sang text cũng được ạ
Vấn đề không ở đó. Tôi đã viết là dữ liệu không ăn nhằm gì với dạng cột Y. Đang có một loạt kiểu ATO-42835577, tự dưng nhẩy ra 42963005
- Về phần dữ liệu mới mà em muốn nối tiếp sang sheet history tức là nếu phần dữ liệu từ cột A đến Y có ở sheet summary mà không có ở sheet historys thì lấy phần dữ liệu không có từ cột A đến Y đó chuyển sang thêm nối tiếp vào sheet historys,
Tôi viết rất rõ là code tôi viết cho giả thiết nhất định. Trong giả thiết đó tôi chấp nhận một khái niệm "dữ liệu mới" cụ thể. Bạn đọc bài #7 thì thấy tôi nêu ra 2 khái niệm "dữ liệu mới". Khi viết code tôi giả thiết "dữ liệu mới" là khái niệm b. trong bài #7, tức cứ không tồn tại SOL (A) là "dư liệu mới". Còn nếu bạn lại muốn khái niệm a. ̣(chuỗi tổng từ A tới Y) thì khẳng định rõ, tôi sẽ sửa vào buổi tối. Chỗ tôi ở múi giờ sau VN 6 tiếng. Tức 7 giờ VN là 1 giờ đêm ở chỗ tôi.
 
Upvote 0
Thêm một cách nữa cho bạn rộng đường lựa chọn.
Hãy vào Sh History(Thu) và nhấn nút để xem và kiểm tra kết quả.
Bạn hãy thử thêm dữ liệu của Sh SUMMARY và kiểm tra lại trên sh History. các sh khác cũng vậy. Tôi đã mất cả một ngày để làm chức năng này theo yêu cầu "
....mỗi lần các sheet khác thay đổi nội dung thì các vùng bên sheet History cũng được cập nhật theo
và nếu dữ liệu ở các sheet summary hay các sheet khác bị mất thì dữ liệu trong sheet historys không bị mất đi...."
này của bạn.
nhớ là kiểm tra thật kỹ. Tôi cũng chưa kiểm tra kỹ được đâu.
Các Sub History cũ của bạn tôi đã xóa bỏ và viết lại (nó chỉ cần đến khi nào bạn muốn sử dụng để Refersh toàn bộ-Dễ kiểm tra)
Xem file đính kèm.
Ngóng chờ hồi âm
em cám ơn anh đã bỏ thời gian giúp đỡ
File của anh lúc tải về enable macro hiển thị lỗi, sau đó chạy code thì không lấy được dữ liệu mới từ sheet summary vào sheet historys, chỉ cập nhật được dữ liệu của các vùng,
và định dạng thời gian bị sai với sheet summary, em biết là định dạng gốc có vấn đề nhưng trước đó
em có lấy được đoạn code
Sarr(k, 3) = Format(DR(i, 3), "dd/mmm/yyyy")
Sarr(k, 4) = Format(DR(i, 4), "dd/mmm/yyyy")
Sarr(k, 5) = Format(DR(i, 5), "dd/mmm/yyyy")
may mắn sao nó lại chạy được a có thể xem file ở bài viết một còn giờ thì em không biết chỉnh thế nào nữa.
a sửa giúp em nhé

Capture.PNG
Bài đã được tự động gộp:

Tôi không bao giờ chấp nhận kiểu Format như thế. Đâu có phải trên máy nào cũng dùng "/" và ngày trước tháng. Vd. ở máy tôi là 20.12.2021. Nếu nói về ngày tháng chuẩn thì tôi khuyên là chuyển ngay dữ liệu gốc về chuẩn. Thế thôi. vd. cột SUMMARY!C. Có thể cho là dữ liệu từ cùng một nguồn nên cùng dạng. Nhìn có 23/11/2021 nên có thể cho là dữ liệu kiểu dd/MM/yyyy. Vậy thì để chuyển C về chuẩn thì: chọn tất cả dữ liệu cột C -> thẻ Data -> Text to Columns -> Next -> Next -> chọn Date -> bên cạnh chọn DMY -> nhấn Finish.

Vấn đề không ở đó. Tôi đã viết là dữ liệu không ăn nhằm gì với dạng cột Y. Đang có một loạt kiểu ATO-42835577, tự dưng nhẩy ra 42963005

Tôi viết rất rõ là code tôi viết cho giả thiết nhất định. Trong giả thiết đó tôi chấp nhận một khái niệm "dữ liệu mới" cụ thể. Bạn đọc bài #7 thì thấy tôi nêu ra 2 khái niệm "dữ liệu mới". Khi viết code tôi giả thiết "dữ liệu mới" là khái niệm b. trong bài #7, tức cứ không tồn tại SOL (A) là "dư liệu mới". Còn nếu bạn lại muốn khái niệm a. ̣(chuỗi tổng từ A tới Y) thì khẳng định rõ, tôi sẽ sửa vào buổi tối. Chỗ tôi ở múi giờ sau VN 6 tiếng. Tức 7 giờ VN là 1 giờ đêm ở chỗ tôi.
thẻ Data -> Text to Columns -> Next -> Next -> chọn Date -> bên cạnh chọn DMY -> nhấn Finish.
Dạ cách này em đã thử rồi ạ nhưng mà nó chỉ được một thời gian sau đó định dạng đó lại trở về lúc ban đầu
vì định dạng gốc là sheet FRU được truy vấn từ hệ thống oracle nên là với em nó rất phức tạp khâu lấy dữ liệu thì do người nước ngoài chạy truy vấn, cho nên a cứ sửa giúp em nếu được như file ở bài một thì tốt quá, còn việc chạy trên máy khác thì không lo ạ vì chỉ lưu hành để xem nội bộ, các máy nội bộ đều xem được ngày tháng như file em đề cập ở bài một.

Vấn đề không ở đó. Tôi đã viết là dữ liệu không ăn nhằm gì với dạng cột Y. Đang có một loạt kiểu ATO-42835577, tự dưng nhẩy ra 42963005 -> cái này cũng không sao anh nhé.

Còn nếu bạn lại muốn khái niệm a. ̣(chuỗi tổng từ A tới Y) thì khẳng định rõ, tôi sẽ sửa vào buổi tối. Chỗ tôi ở múi giờ sau VN 6 tiếng. Tức 7 giờ VN là 1 giờ đêm ở chỗ tôi. -> em xác nhận là lấy từ A đến Y a nhé. dạ em hiểu lệch mũi giờ khiến a vất vả nên khi nào a rảnh a sửa giúp em cũng được ạ
 
Lần chỉnh sửa cuối:
Upvote 0
Dạ cách này em đã thử rồi ạ nhưng mà nó chỉ được một thời gian sau đó định dạng đó lại trở về lúc ban đầu
vì định dạng gốc là sheet FRU được truy vấn từ hệ thống oracle nên là với em nó rất phức tạp khâu lấy dữ liệu thì do người nước ngoài chạy truy vấn, cho nên a cứ sửa giúp em nếu được như file ở bài một thì tốt quá, còn việc chạy trên máy khác thì không lo ạ vì chỉ lưu hành để xem nội bộ, các máy nội bộ đều xem được ngày tháng như file em đề cập ở bài một.
Tôi đã nói rồi, tôi không xem code cũ của bạn, tôi không sửa theo ý bạn.

Thao tác mà tôi hướng dẫn chỉ mất chưa tới 1 phút. Cứ cho là thỉnh thoảng (vài ngày?) lại phải mất 1 phút thì chả là gì cả. Nếu cần thì tôi sẽ viết code để đưa C, D, E về chuẩn trước khi duyệt SUMMARY chứ không phải kiểu chữa cháy bằng Format. Còn các cột X, Y, M thì bạn phải chỉnh lại.

Về vấn đề "dữ liệu mới" bạn phải khẳng ̣định rõ lại là theo a. ở bài #7 hay không. Lúc đó tôi mới sửa lại code.
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi đã nói rồi, tôi không xem code cũ của bạn, tôi không sửa theo ý bạn.

Thao tác mà tôi hướng dẫn chỉ mất chưa tới 1 phút. Cứ cho là thỉnh thoảng (vài ngày?) lại phải mất 1 phút thì chả là gì cả. Nếu cần thì tôi sẽ viết code để đưa C, D, E về chuẩn trước khi duyệt SUMMARY chứ không phải kiểu chữa cháy bằng Format. Còn các cột X, Y, M thì bạn phải chỉnh lại.

Về vấn đề "dữ liệu mới" bạn phải khẳng ̣định rõ lại là theo a. ở bài #7 hay không. Lúc đó tôi mới sửa lại code.
a. hoặc mới là A & B & ... & Z mới
b. hoặc mới là A mới

Phương án A a nhé. a sửa Z thành Y giúp em ạ

Thao tác mà tôi hướng dẫn chỉ mất chưa tới 1 phút. Cứ cho là thỉnh thoảng (vài ngày?) lại phải mất 1 phút thì chả là gì cả. Nếu cần thì tôi sẽ viết code để đưa C, D, E về chuẩn trước khi duyệt SUMMARY chứ không phải kiểu chữa cháy bằng Format.
-> Dạ đúng là chỉ mất 1 vài phút, nhưng mà vấn đề em gặp phải không dừng lại ở đó, cứ 5 phút sẽ có hệ thống khác tự động lấy file này lên để tính toán, nếu Text to Columns thì việc này lặp đi lặp lại chưa kể là lúc về nhà rồi nhưng hệ thống vẫn hoạt động, nếu ngày khác nhau thì em cũng không biết phải làm sao nữa,
chuyển về định dạng chuẩn trước khi duyệt thì cũng rủi ro cao vì ngày có 2 chữ số tháng cũng có 2 chữ số, hệ thống nó cũng không biết được đâu là ngày đâu là tháng,nó chỉ nhận dạng được tháng qua "MMM" vì dụ là Dec hay Oct ... cho nên em mới phải làm format như vậy, nếu không vướng hệ thống em cũng cặm cụi vlookup chứ không dám đăng bài lên đây ạ
 
Upvote 0
-> Dạ đúng là chỉ mất 1 vài phút, nhưng mà vấn đề em gặp phải không dừng lại ở đó, cứ 5 phút sẽ có hệ thống khác tự động lấy file này lên để tính toán, nếu Text to Columns thì việc này lặp đi lặp lại chưa kể là lúc về nhà rồi nhưng hệ thống vẫn hoạt động, nếu ngày khác nhau thì em cũng không biết phải làm sao nữa,
chuyển về định dạng chuẩn trước khi duyệt thì cũng rủi ro cao vì ngày có 2 chữ số tháng cũng có 2 chữ số, hệ thống nó cũng không biết được đâu là ngày đâu là tháng,nó chỉ nhận dạng được tháng qua "MMM" vì dụ là Dec hay Oct ... cho nên em mới phải làm format như vậy, nếu không vướng hệ thống em cũng cặm cụi vlookup chứ không dám đăng bài lên đây ạ
Tôi không hiểu bạn nói gì. Ngày tháng chuẩn chỉ khác ngày tháng nhái của bạn ở chỗ nó là hàng xịn. Còn chuyện bạn định dạng thế nào thì đâu có liên quan. Vd. có ngày tháng xin 20.12.2021 có thể định dạng là vd. "20 Dec 2021", hoặc "20 tháng Mười Hai 2021" hay "ngày 20 lành tháng 12 tốt năm 2021 xịn"
Ngày tháng chuẩn và định dạng là 2 vấn đề khác nhau. Ở đâu ra cái hệ thống chấp nhậ̣n hàng nhái và từ chối hàng xin vậy?
 
Upvote 0
Tôi không hiểu bạn nói gì. Ngày tháng chuẩn chỉ khác ngày tháng nhái của bạn ở chỗ nó là hàng xịn. Còn chuyện bạn định dạng thế nào thì đâu có liên quan. Vd. có ngày tháng xin 20.12.2021 có thể định dạng là vd. "20 Dec 2021", hoặc "20 tháng Mười Hai 2021" hay "20 ngày lành tháng 12 tốt năm 2021 xịn"
Ngày tháng chuẩn và định dạng là 2 vấ đề khác nhau. Ở đâu ra cái hệ thống chấp nhậ̣n hàng nhái và từ chối hàng xin vậy?
Hệ thống từ năm 1995 anh ạ, không được nâng cấp và họ cứ duy trì vậy, nhưng đây ko phải do hệ thống mà do dữ liệu gốc như a đã phản ảnh là không đạt chuẩn, em cũng không biết diễn tả làm sao nữa càng nói khiến a cũng sẽ khó hiểu, em từ một kế toán rồi khi vào làm với hệ thống này trở nên không bình thường nữa
 
Upvote 0
em cám ơn anh đã bỏ thời gian giúp đỡ
File của anh lúc tải về enable macro hiển thị lỗi, sau đó chạy code thì không lấy được dữ liệu mới từ sheet summary vào sheet historys, chỉ cập nhật được dữ liệu của các vùng,
và định dạng thời gian bị sai với sheet summary, em biết là định dạng gốc có vấn đề nhưng trước đó
em có lấy được đoạn code
Sarr(k, 3) = Format(DR(i, 3), "dd/mmm/yyyy")
Sarr(k, 4) = Format(DR(i, 4), "dd/mmm/yyyy")
Sarr(k, 5) = Format(DR(i, 5), "dd/mmm/yyyy")
may mắn sao nó lại chạy được a có thể xem file ở bài viết một còn giờ thì em không biết chỉnh thế nào nữa.
a sửa giúp em nhé

View attachment 270535
Lỗi này có thể là do tôi đã đặt code khi mở workbook sẽ addDic, hoặc có thể không tương thích với máy bạn. Chứ ở máy tôi nó chạy bình thường mà, không muốn nói là rất nhanh nữa là đằng khác. Bạn thử tìm hiểu xem lỗi này là gì thì có cách giải quyết thôi. google dịch thành Phương thức 'Trang tính' của đối tượng '_Global' bị lỗi.
Bạn end nó đi và mở VBE ra chạy code history xem thế nào? nếu không thì bạn chạy modul napdic trước sau đó chạy modul Refresh All xem có ra không?
 
Upvote 0
Hệ thống từ năm 1995 anh ạ, không được nâng cấp và họ cứ duy trì vậy, nhưng đây ko phải do hệ thống mà do dữ liệu gốc như a đã phản ảnh là không đạt chuẩn, em cũng không biết diễn tả làm sao nữa càng nói khiến a cũng sẽ khó hiểu, em từ một kế toán rồi khi vào làm với hệ thống này trở nên không bình thường nữa
Thì tôi cũng viết rồi. Đưa về ngày tháng xịn thôi, còn định dạng như nào thì bạn tự định dạng từng cột sẵn thôi. Bạn viện lý do này nọ nhưng tôi có câu hỏi. Trong SUMMARY các cột C, D, E chứa ngày tháng không chuẩn, trong khi các cột I, J, K, Z, AB, AC, AE, AK, AL cũng chứa ngày tháng nhưng là ngày tháng xịn. Bạn lấy lý do là hệ thống không chấp nhận ngày tháng chuẩn? Thế thì sao hệ thống không gào lên khi mà I, J, K, Z, AB, AC, AE, AK, AL đều có ngày tháng chuẩn?
 
Upvote 0
Lỗi này có thể là do tôi đã đặt code khi mở workbook sẽ addDic, hoặc có thể không tương thích với máy bạn. Chứ ở máy tôi nó chạy bình thường mà, không muốn nói là rất nhanh nữa là đằng khác. Bạn thử tìm hiểu xem lỗi này là gì thì có cách giải quyết thôi. google dịch thành Phương thức 'Trang tính' của đối tượng '_Global' bị lỗi.
Bạn end nó đi và mở VBE ra chạy code history xem thế nào? nếu không thì bạn chạy modul napdic trước sau đó chạy modul Refresh All xem có ra không?
Em chạy được rồi a nhé, vậy mỗi lần chạy
Thì tôi cũng viết rồi. Đưa về ngày tháng xịn thôi, còn định dạng như nào thì bạn tự định dạng từng cột sẵn thôi. Bạn viện lý do này nọ nhưng tôi có câu hỏi. Trong SUMMARY các cột C, D, E chứa ngày tháng không chuẩn, trong khi các cột I, J, K, Z, AB, AC, AE, AK, AL cũng chứa ngày tháng nhưng là ngày tháng xịn. Bạn lấy lý do là hệ thống không chấp nhận ngày tháng chuẩn? Thế thì sao hệ thống không gào lên khi mà I, J, K, Z, AB, AC, AE, AK, AL đều có ngày tháng chuẩn?
Dạ các cột mà a nói có ngày tháng chuẩn là toàn bộ được nhập bằng tay từ file excel sau đó import vào hệ thống, còn C D E là định dạng không chuẩn được cắt xén từ nhiều nguồn khác nhau dẫn đến như vậy nên em phải dùng tạm format để chuyển đổi thành dạng tháng MMM để phân biệt với ngày thì hệ thống nó mới không báo lỗi
Bài đã được tự động gộp:

Lỗi này có thể là do tôi đã đặt code khi mở workbook sẽ addDic, hoặc có thể không tương thích với máy bạn. Chứ ở máy tôi nó chạy bình thường mà, không muốn nói là rất nhanh nữa là đằng khác. Bạn thử tìm hiểu xem lỗi này là gì thì có cách giải quyết thôi. google dịch thành Phương thức 'Trang tính' của đối tượng '_Global' bị lỗi.
Bạn end nó đi và mở VBE ra chạy code history xem thế nào? nếu không thì bạn chạy modul napdic trước sau đó chạy modul Refresh All xem có ra không?
Dạ em vừa chạy được a nhé, vậy sau này phải chạy module napdic trước phải không anh
 
Upvote 0
Dạ em vừa chạy được a nhé, vậy sau này phải chạy module napdic trước phải không anh
Chúc mừng bạn.

Nhưng bạn đã mô tả cách làm sai hoàn toàn. Từ cách mô tả đại loại là: "nếu dữ liệu SUMMARY đã tồn tại thì làm mới các cột B,C,D,E và S của sheet historys. Còn nếu là dữ liệu mới thì copy toàn bộ dòng A:Y sang HISTORYS". Từ mô tả trên có 2 kết luận:

1. Nếu có khái niệm "dữ liệu của dòng nào đó của SUMMARY ĐÃ TỒN TẠI bên HISTORYS" thì có nghĩa là trước khi chạy code thì HISTORYS có thể đã có dữ liệu rồi. Trong khi đó tập tin HISTIRYS(Thu) trắng tinh.

2. Code đơn giản chỉ copy SUMMARY!A2:Y... sang HISTORYS!A2:Y... chứ có bận tâm gì tới cái gọi là "dữ liệu mới", "dữ liệu cũ" đâu nhỉ. Có bận tâm làm mới các cột B,C,D,E và S của sheet historys đâu nhỉ. Có phải bận tâm ... đâu nhỉ. Hay là tôi sơ ý không nhìn thấy?

Tôi không hiểu ý nên hỏi ở bài 4 và các bài tiếp theo. Nếu cách làm như ở trên thì chỉ cần mô tả 1 câu: "Khi duyệt SUMMARY thì bê hết dữ liệu của nó, cột từ A đến Y rồi ghi đè lên HISTORYS bắt đầu từ A2". Đơn giản thế thôi chứ "dữ liệu mới", "dữ liệu cũ" từ A đến Y, làm mới các cột B,C,D,E và S của sheet historys ... để làm gì. Mất bao nhiêu thời gian
 
Upvote 0
Em chạy được rồi a nhé, vậy mỗi lần chạy.
Dạ em vừa chạy được a nhé, vậy sau này phải chạy module napdic trước phải không anh
Tôi đã code NapDic (Sub AddDic) ở sự kiện open Workbook rồi, và như vậy không biết có đúng không. Bạn thử thì biết ngay thôi mà. Tắt bỏ Workbook rồi mở lại sauddos vào Sh History (thu) và nhấn nút xem nó có Import không? nếu lỗi thì chụp cái lỗi đó gửi lên.
 
Upvote 0
Chúc mừng bạn.

Nhưng bạn đã mô tả cách làm sai hoàn toàn. Từ cách mô tả đại loại là: "nếu dữ liệu SUMMARY đã tồn tại thì làm mới các cột B,C,D,E và S của sheet historys. Còn nếu là dữ liệu mới thì copy toàn bộ dòng A:Y sang HISTORYS". Từ mô tả trên có 2 kết luận:

1. Nếu có khái niệm "dữ liệu của dòng nào đó của SUMMARY ĐÃ TỒN TẠI bên HISTORYS" thì có nghĩa là trước khi chạy code thì HISTORYS có thể đã có dữ liệu rồi. Trong khi đó tập tin HISTIRYS(Thu) trắng tinh.

2. Code đơn giản chỉ copy SUMMARY!A2:Y... sang HISTORYS!A2:Y... chứ có bận tâm gì tới cái gọi là "dữ liệu mới", "dữ liệu cũ" đâu nhỉ. Có bận tâm làm mới các cột B,C,D,E và S của sheet historys đâu nhỉ. Có phải bận tâm ... đâu nhỉ. Hay là tôi sơ ý không nhìn thấy?

Tôi không hiểu ý nên hỏi ở bài 4 và các bài tiếp theo. Nếu cách làm như ở trên thì chỉ cần mô tả 1 câu: "Khi duyệt SUMMARY thì bê hết dữ liệu của nó, cột từ A đến Y rồi ghi đè lên HISTORYS bắt đầu từ A2". Đơn giản thế thôi chứ "dữ liệu mới", "dữ liệu cũ" từ A đến Y, làm mới các cột B,C,D,E và S của sheet historys ... để làm gì. Mất bao nhiêu thời gian
Dạ vì sheet summary sẽ mất đi dữ liệu theo thời gian nên mới cần cập nhật sang hisyorys để bảo toàn anh ạ, nếu ghi đè lên thì mất hết dữ liệu cũ, hàng ngày trong sheet summary sẽ có dữ liệu mới từ A đến Y được sinh ra và đồng thời dữ liệu cũ cũng sẽ bị mất đi cho nên em diễn tả làm anh khó hiểu chút ạ
 
Lần chỉnh sửa cuối:
Upvote 0
Dạ vì sheet summary sẽ mất đi dữ liệu theo thời gian nên mới cần cập nhật sang hisyorys để bảo toàn anh ạ, nếu ghi đè lên thì mất hết dữ liệu cũ,
Thế bạn đã kiểm tra chưa? Theo tôi thì code (code mà bạn khoe là đã chạy được ấy) đang ghi đè, nhưng tôi chỉ là người nên có thể không nhìn thấy.

Bạn mô tả một đường nhưng code làm một nẻo. Nhưng bạn hài lòng nên tôi hơi ngạc nhiên thôi. Còn nếu cuối cùng bạn muốn thế thì đó là quyền của bạn.
 
Upvote 0
Thế bạn đã kiểm tra chưa? Theo tôi thì code (code mà bạn khoe là đã chạy được ấy) đang ghi đè, nhưng tôi chỉ là người nên có thể không nhìn thấy.

Bạn mô tả một đường nhưng code làm một nẻo. Nhưng bạn hài lòng nên tôi hơi ngạc nhiên thôi. Còn nếu cuối cùng bạn muốn thế thì đó là quyền của bạn.
Em đang hiểu ý anh là đè lên tất cả historys nên em mới bảo là ghi đè vậy sẽ mất cả dữ liệu cũ, còn file em gửi là ghi đè dữ liệu cũ và lấy dữ liệu mới sau đó cập nhật cho các vùng, code mà a đưa em đã chạy đúng như em đang cần mà,
chỉ còn thời gian từ C D E thôi ạ, giờ em không biết chuyển đổi làm sao để nó được như file ban đầu.
 
Upvote 0
Em đang hiểu ý anh là đè lên tất cả historys nên em mới bảo là ghi đè vậy sẽ mất cả dữ liệu cũ, còn file em gửi là ghi đè dữ liệu cũ và lấy dữ liệu mới sau đó cập nhật cho các vùng, code mà a đưa em đã chạy đúng như em đang cần mà,
chỉ còn thời gian từ C D E thôi ạ, giờ em không biết chuyển đổi làm sao để nó được như file ban đầu.
Bạn nên theo dõi xem người ta trích gì, trích ai để biết người ta đang nói tới bài nào, tới ai.

Tôi trích bài chính xác mà.

Trong bài 19 tôi viết

Chúc mừng bạn.

sau khi trích bài 18 của bạn
Dạ em vừa chạy được a nhé, vậy sau này phải chạy module napdic trước phải không anh

Trong bài 18 bạn trích bài và trả lời bài 16. Tác giả bài 16 đính kèm tập tin ở bài 9.

Tóm lại bạn khoe là đã chạy được code bài 9. Tôi chúc mừng và phân tích bài 9 nhưng bạn cố tình không hiểu. Vậy tôi dẫn chứng.
Sub RefershAll()

Application.ScreenUpdating = False
...
If Dic Is Nothing Then Call AddDic
Sheets("HISTORYS(Thu)").Cells(2, 1).Resize(65500, 43).ClearContents
Sheets("HISTORYS(Thu)").Cells(2, 1).Resize(R, 25) = Arr
...

Trong code RefershAll có gọi sub AddDic
Sub AddDic()
Dim MATER()
...
Lr = Sheets("SUMMARY").Range("A65500").End(xlUp).Row
Arr = Sheets("SUMMARY").Range("A2:Y" & Lr).Value
...

Tức lấy vùng A2:Y..., tức toàn bộ các dòng dữ liệu, từ SUMMARY vào mảng Arr.

Sau đó trong RefershAll ở dòng

Sheets("HISTORYS(Thu)").Cells(2, 1).Resize(R, 25) = Arr

mảng Arr kia được đập vào HISTORYS bắt đầu từ A2. Thế không là ghi đè thì là gì hả bạn?

Tôi kết thúc ở đây.
 
Upvote 0
Bạn nên theo dõi xem người ta trích gì, trích ai để biết người ta đang nói tới bài nào, tới ai.

Tôi trích bài chính xác mà.

Trong bài 19 tôi viết

Chúc mừng bạn.

sau khi trích bài 18 của bạn


Trong bài 18 bạn trích bài và trả lời bài 16. Tác giả bài 16 đính kèm tập tin ở bài 9.

Tóm lại bạn khoe là đã chạy được code bài 9. Tôi chúc mừng và phân tích bài 9 nhưng bạn cố tình không hiểu. Vậy tôi dẫn chứng.


Trong code RefershAll có gọi sub AddDic


Tức lấy vùng A2:Y..., tức toàn bộ các dòng dữ liệu, từ SUMMARY vào mảng Arr.

Sau đó trong RefershAll ở dòng

Sheets("HISTORYS(Thu)").Cells(2, 1).Resize(R, 25) = Arr

mảng Arr kia được đập vào HISTORYS bắt đầu từ A2. Thế không là ghi đè thì là gì hả bạn?

Tôi kết thúc ở đây.
vâng em cám ơn anh.
 
Upvote 0
Thông qua là cái khỉ gì. Tôi đang nói tới:
a. hoặc mới là A & B & ... & Z mới
b. hoặc mới là A mới

Vd. Bên HISTORYS có A = 12345, B = "blala, C = "hic hic", Bên SUMMARY có A = 12345, B = "blala, C = "he he". Vậy đó có là DỮ LIỆU MỚI không? Theo a. thì là DỮ LIỆU MỚI do "12345blalahe he" <> "12345blalahic hic", còn theo b. thì không là dữ liệu mới vì 12345 (SUMMARY) = 12345 (HISTORYS).

Hoặc mới là khi ít nhất 1 cột trong A:Z là mới, hoặc mới là khi có A mới. Làm gì có kiểu: mới khi ít nhất 1 cột trong A:Z là mới THÔNG QUA cột A.

Thôi tôi không đọc tiếp nữa. Tôi sẽ làm theo một giả thiết nhất định.

1. Trước hết duyệt SUMMARY. kiểm tra từng SOL có trong cột A của HISTORYS không. Nếu có rồi thì cập nhật B,C,D,E và S của sheet historys. Nếu chưa có SOL đang xét trong HISTORYS!A thì toàn bộ dòng có SOL đó từ A tới Y được nhập vào dòng cuối bên HISTORYS.

2. Sau khi duyệt SUMMARY thì duyệt các sheet khác theo mô tả ở bài #3.

3. Tôi không dò code của bạn, mệt lắm. Tôi thử đập đi xây mới. Tôi viết lại Sub History

4. Có nhiều cái bạn phải kiểm tra lại.

1. Trong SUMMARY dạng dữ liệu X572:X573, Y572:Y573 (đều là các số) không ăn nhập gì với dạng của cột X và Y (dạng text). Tương tự Y2470, M174:M185, và nhiều khoảng nữa trong cột M. Vì thế sang HISTORYS cũng kỳ cục - X566:Y567 và Y2464, và M173:M184 và nhiều khoảng nữa trong cột M

2. Trong SUMMARY chắc chắn cột C, D và E không có ngày tháng chuẩn, và chúng được coi là có dạng MM/dd/yyyy. Vì thế khi chạy trên máy bạn thì có thể sẽ có vd. HISTORYS!C2 = 06 tháng 10 năm 2021, nhưng khi chạy code ở máy tôi sẽ có HISTORYS!C2 = 10 tháng 06 năm 2021. Nguyên nhân là do SUMMARY!C2 không là ngày tháng chuẩn - khi mở trên máy tôi C2 được căn trái. Trên máy tôi thì sau khi chạy code trong HISTORYS!C, D, E hoặc sẽ có ngày tháng chuẩn nhưng ngày tháng sẽ bị đổi chỗ (bên SUMMARY có số đầu < 13), hoặc ngày tháng "nhái" (bên SUMMARY số đầu > 12), chúng được bê y nguyên từ SUMMARY sang HISTORYS .

Tóm lại nếu nói về dữ liệu nguồn trong SUMMARY thì phải kiểm tra lại cột C, D, E (ngày tháng không chuẩn), và cột M, X, Y - định dạng ô không phù hợp, dạng dữ liệu không ăn nhập gì với dạng của cột, tức khác với dạng của các dữ liệu khác trong cùng cột.

Tất nhiên phải kiểm tra xem kết quả code có đúng ý không.
Anh ơi, trong trường hợp em muốn thêm sheet thì em sửa code thế nào vậy anh, em có chỉnh thêm trong này rồi nhưng không biết phải chỉnh ở đâu nữa.
ZAQ_historys = .Range("AA2:AS" & lastRow).Value

Mã:
 thong_tin = Array( _
        Array("SHIPOUT", "ORDER_SCAN", "BY_DATE", "KITTING", "MATERIAL_SHORTAGE", "PRINT_STAGE", "CUT_STAGE", "BCNK", "SOL_CANCEL", "MATER_ITEM", "BALANCE_LOCATION"), _
        Array("A", "A", "A", "A", "B", "A", "A", "B", "A", "A", "A"), _
        Array("B", "C", "B", "B", "N", "B", "B", "C", "B", "E", "E"), _
        Array(2, 1, 1, 1, 1, 3, 3, 2, 1, 3, 1), _
        Array(1, 3, 17, 4, 5, 6, 9, 12, 18, 14, 19))
 
Upvote 0
Anh ơi, trong trường hợp em muốn thêm sheet thì em sửa code thế nào vậy anh, em có chỉnh thêm trong này rồi nhưng không biết phải chỉnh ở đâu nữa.
ZAQ_historys = .Range("AA2:AS" & lastRow).Value

Mã:
 thong_tin = Array( _
        Array("SHIPOUT", "ORDER_SCAN", "BY_DATE", "KITTING", "MATERIAL_SHORTAGE", "PRINT_STAGE", "CUT_STAGE", "BCNK", "SOL_CANCEL", "MATER_ITEM", "BALANCE_LOCATION"), _
        Array("A", "A", "A", "A", "B", "A", "A", "B", "A", "A", "A"), _
        Array("B", "C", "B", "B", "N", "B", "B", "C", "B", "E", "E"), _
        Array(2, 1, 1, 1, 1, 3, 3, 2, 1, 3, 1), _
        Array(1, 3, 17, 4, 5, 6, 9, 12, 18, 14, 19))
Về đoạn mà bạn hỏi trong đoạn trích ở trên thì ...
Bạn cần hiểu là ZAQ_historys có nghĩa là lấy vùng từ cột Z tới cột AQ của HISTORYS vào mảng ZAQ_historys. Vì thế không có chuyện ZAQ_historys = .Range("AA2:AS" & lastRow).Value - tức không có chuyện lấy từ cột AA tới AS vào mảng ZAQ_historys đâu.

Bạn để ý là trong mảng thong_tin sheet MATER_ITEM được đặt cuối cùng. Vì sao? Vì khi duyệt các sheet khác thì đều lấy SOL ở cột A của HISTOSYS để tìm trong cột A của sheet đang duyệt. Chỉ tới khi duyệt MATER_ITEM mới lấy ITEM từ cột L của HISTORYS để tìm trong cột A của MATER_ITEM. Vì thế khi duyệt các sheet khác thì ta luôn dùng chung 1 dic, chỉ khi duyệt tới giá trị cuối cùng của vòng FOR ta mới tạo dic mới để làm bảng dò cho MATER_ITEM. Chính vì thế khi thêm sheet thì không thể đặt sau MATER_ITEM được. Và nữa: hiện tại ta chỉ tìm cột A hoặc L của HISTORYS trong các sheet. Thế với sheet thêm thì tìm cột nào của HISTORYS trong sheet thêm? Nếu không là A mà cũng không là L thì còn sửa nữa, vì bảng dò (dic) cũng phải tạo khi duyệt sheet thêm. Tóm lại phải mô tả về sheet thêm này (cách duyệt, khi tìm thấy thì lấy những cột nào để làm mới HISTORYS ...) thì mới nói chuyện được.
--------------

Lẽ ra bạn nên hỏi HUONGHCKT. Theo tôi thì bạn mô tả một đằng còn HUONGHCKT làm một nẻo. Nhưng nếu bạn đổi ý và hài lòng với code đó thì đó là quyền của bạn.

Bạn phải tự test kỹ vì nếu không thì không có gì đảm bảo là code của bất kỳ ai đó cũng làm làm đúng yêu cầu của bạn.
Nếu bạn cuối cùng cho là code của HUONGHCKT chưa làm đúng yêu cầu của bạn thì bạn phải nói rõ ra và nhờ HUONGHCKT sửa lại. Cho tới tận giờ bạn không nói ra và nhờ sửa thì HUONGHCKT có quyền cho là code đã làm đúng yêu cầu của bạn.

Bạn nên nhờ tiếp HUONGHCKT vì code của tôi nếu có đúng thì cũng chỉ là code cho refresh All. Bây giờ đọc kỹ lại bài #1 tôi mới thấy

mỗi lần các sheet khác thay đổi nội dung thì các vùng bên sheet History cũng được cập nhật theo
Cái phần này tôi chưa làm, nhưng tôi thấy HUONGHCKT đã làm cho bạn. Tôi không dám phán là đã đúng ý bạn vì thực ra tôi cũng chưa rõ yêu cầu này. Nhưng HUONGHCKT đã làm thì chỉ cần sửa thôi.

Về phần mình thì nếu thêm cả phần nói ở trên thì có lẽ tôi sẽ viết hơi khác một chút code để sao cho có thể dùng cho refresh All và cả cho cho phần trên. Nhưng tôi chưa hiểu yêu cầu. Tôi trích lại:
mỗi lần các sheet khác thay đổi nội dung thì các vùng bên sheet History cũng được cập nhật theo

Giả sử MỘT DÒNG NÀO ĐÓ của MATER_ITEM thay đổi thì cách làm nào sau đây là đúng yêu cầu (có thể 2 cách đều cho kết quả như nhau ***):

a. tìm từng dữ liệu trong cột L của HISTORYS trong cột A của dòng THAY ĐỔI của MATER_ITEM (chỉ của MATER_ITEM vì không duyệt các sheet không có thay đổi? Đúng là thế hay thế nào?). Nếu không tìm thấy thì không làm gì. Nếu tìm thấy thì lấy dữ liệu tương ứng từ MATER_ITEM sang HISTORYS.

b. tìm từng dữ liệu trong cột L của HISTORYS trong TOÀN BỘ cột A của MATER_ITEM (chỉ của MATER_ITEM vì không duyệt các sheet không có thay đổi? Đúng là thế hay thế nào?). Nếu không tìm thấy thì không làm gì. Nếu tìm thấy thì lấy dữ liệu tương ứng từ MATER_ITEM sang HISTORYS.

Tương tự với các sheet khác. Bạn phải cho biết cách thao tác là theo a. hay b. Nếu thao tác theo b. luôn có thể chấp nhận được thì cũng nói rõ.

***: do tôi không biết dữ liệu trong các sheet xuất hiện và biến mất theo cách nào, qui luật nào nên tôi cho ví dụ khi cách duyệt a. và b. cho hậu quả khác nhau. Vd. hiện tại trong HISTORYS ở ô nào đó của cột L có giá trị 123456789. Trong MATER_ITEM đang có ở cột A giá trị 123456789, và E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ". Khi nhấn nút refresh All thì E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ" được lấy sang HISTORYS sang AM, AN, AO và cùng dòng với 123456789. Bây giờ trong sheet MATER_ITEM ngoài 123456789 đã có ta chèn thêm 1 dòng khác TRƯỚC NÓ có các dữ liệu khác nhau ở các cột khác nhưng ở cột A cũng có 123456789, và E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới". Nếu bây giờ tìm 123456789 lấy từ cột L của HISTORYS trong cột A của MATER_ITEM thì:

- nếu tìm theo cách a. thì kết quả là E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới" được nhập vào AM, AN, AO của HISTORYS và ghi đè lên "ngày mai cũ", "em đi cũ", "biển nhớ cũ".

- nếu tìm theo cách b. thì kết quả là: đầu tiên E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới" được nhập vào AM, AN, AO của HISTORYS (tìm thấy 123456789 ở dòng mới) và ghi đè lên E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ" đang có. Tiếp theo E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ" được nhập vào AM, AN, AO của HISTORYS (tìm thấy 123456789 ở dòng cũ) và ghi đè lên E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới" đang có ở thời điểm này. Kết quả có E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ"

Cách a. và b. cho kết quả khác nhau. Vì tôi không biết dữ liệu trong các sheet thoắt xuất hiện thoắt biến mất như thế nào, theo cách nào, qui luật nào nên tôi buộc phải có những phân tích như trên.

Nhiều người cứ viết theo như họ hiểu nhưng không lưu ý. Nếu họ hiểu sai thì kệ bạn. Bạn không mô tả chính xác cho họ hiểu thì bạn tự lĩnh hậu quả. Nhưng tôi khi không hiểu thì tôi không thể viết được code. Nếu tôi cho là mình hiểu nhưng chưa dám chắc chắn thì tôi luôn lưu ý là code tôi đưa ra được viết cho giả thiết nào.
 
Lần chỉnh sửa cuối:
Upvote 0
Về đoạn mà bạn hỏi trong đoạn trích ở trên thì ...
Bạn cần hiểu là ZAQ_historys có nghĩa là lấy vùng từ cột Z tới cột AQ của HISTORYS vào mảng ZAQ_historys. Vì thế không có chuyện ZAQ_historys = .Range("AA2:AS" & lastRow).Value - tức không có chuyện lấy từ cột AA tới AS vào mảng ZAQ_historys đâu.

Bạn để ý là trong mảng thong_tin sheet MATER_ITEM được đặt cuối cùng. Vì sao? Vì khi duyệt các sheet khác thì đều lấy SOL ở cột A của HISTOSYS để tìm trong cột A của sheet đang duyệt. Chỉ tới khi duyệt MATER_ITEM mới lấy ITEM từ cột L của HISTORYS để tìm trong cột A của MATER_ITEM. Vì thế khi duyệt các sheet khác thì ta luôn dùng chung 1 dic, chỉ khi duyệt tới giá trị cuối cùng của vòng FOR ta mới tạo dic mới để làm bảng dò cho MATER_ITEM. Chính vì thế khi thêm sheet thì không thể đặt sau MATER_ITEM được. Và nữa: hiện tại ta chỉ tìm cột A hoặc L của HISTORYS trong các sheet. Thế với sheet thêm thì tìm cột nào của HISTORYS trong sheet thêm? Nếu không là A mà cũng không là L thì còn sửa nữa, vì bảng dò (dic) cũng phải tạo khi duyệt sheet thêm. Tóm lại phải mô tả về sheet thêm này (cách duyệt, khi tìm thấy thì lấy những cột nào để làm mới HISTORYS ...) thì mới nói chuyện được.
--------------

Lẽ ra bạn nên hỏi HUONGHCKT. Theo tôi thì bạn mô tả một đằng còn HUONGHCKT làm một nẻo. Nhưng nếu bạn đổi ý và hài lòng với code đó thì đó là quyền của bạn.

Bạn phải tự test kỹ vì nếu không thì không có gì đảm bảo là code của bất kỳ ai đó cũng làm làm đúng yêu cầu của bạn.
Nếu bạn cuối cùng cho là code của HUONGHCKT chưa làm đúng yêu cầu của bạn thì bạn phải nói rõ ra và nhờ HUONGHCKT sửa lại. Cho tới tận giờ bạn không nói ra và nhờ sửa thì HUONGHCKT có quyền cho là code đã làm đúng yêu cầu của bạn.

Bạn nên nhờ tiếp HUONGHCKT vì code của tôi nếu có đúng thì cũng chỉ là code cho refresh All. Bây giờ đọc kỹ lại bài #1 tôi mới thấy


Cái phần này tôi chưa làm, nhưng tôi thấy HUONGHCKT đã làm cho bạn. Tôi không dám phán là đã đúng ý bạn vì thực ra tôi cũng chưa rõ yêu cầu này. Nhưng HUONGHCKT đã làm thì chỉ cần sửa thôi.

Về phần mình thì nếu thêm cả phần nói ở trên thì có lẽ tôi sẽ viết hơi khác một chút code để sao cho có thể dùng cho refresh All và cả cho cho phần trên. Nhưng tôi chưa hiểu yêu cầu. Tôi trích lại:


Giả sử MỘT DÒNG NÀO ĐÓ của MATER_ITEM thay đổi thì cách làm nào sau đây là đúng yêu cầu (có thể 2 cách đều cho kết quả như nhau ***):

a. tìm từng dữ liệu trong cột L của HISTORYS trong cột A của dòng THAY ĐỔI của MATER_ITEM (chỉ của MATER_ITEM vì không duyệt các sheet không có thay đổi? Đúng là thế hay thế nào?). Nếu không tìm thấy thì không làm gì. Nếu tìm thấy thì lấy dữ liệu tương ứng từ MATER_ITEM sang HISTORYS.

b. tìm từng dữ liệu trong cột L của HISTORYS trong TOÀN BỘ cột A của MATER_ITEM (chỉ của MATER_ITEM vì không duyệt các sheet không có thay đổi? Đúng là thế hay thế nào?). Nếu không tìm thấy thì không làm gì. Nếu tìm thấy thì lấy dữ liệu tương ứng từ MATER_ITEM sang HISTORYS.

Tương tự với các sheet khác. Bạn phải cho biết cách thao tác là theo a. hay b.

***: do tôi không biết dữ liệu trong các sheet xuất hiện và biến mất theo cách nào, qui luật nào nên tôi cho ví dụ khi cách duyệt a. và b. cho hậu quả khác nhau. Vd. hiện tại trong HISTORYS ở ô nào đó của cột L có giá trị 123456789. Trong MATER_ITEM đang có ở cột A giá trị 123456789, và E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ". Khi nhấn nút refresh All thì E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ" được lấy sang HISTORYS sang AM, AN, AO và cùng dòng với 123456789. Bây giờ trong sheet MATER_ITEM ngoài 123456789 đã có ta chèn thêm 1 dòng khác TRƯỚC NÓ có các dữ liệu khác nhau ở các cột khác nhưng ở cột A cũng có 123456789, và E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới". Nếu bây giờ tìm 123456789 lấy từ cột L của HISTORYS trong cột A của MATER_ITEM thì:

- nếu tìm theo cách a. thì kết quả là E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới" được nhập vào AM, AN, AO của HISTORYS và ghi đè lên "ngày mai cũ", "em đi cũ", "biển nhớ cũ".

- nếu tìm theo cách b. thì kết quả là: đầu tiên E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới" được nhập vào AM, AN, AO của HISTORYS (tìm thấy 123456789 ở dòng mới) và ghi đè lên E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ" đang có. Tiếp theo E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ" được nhập vào AM, AN, AO của HISTORYS (tìm thấy 123456789 ở dòng cũ) và ghi đè lên E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới" đang có ở thời điểm này. Kết quả có E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ"

Cách a. và b. cho kết quả khác nhau. Vì tôi không biết dữ liệu trong các sheet thoắt xuất hiện thoắt biến mất như thế nào, theo cách nào, qui luật nào nên tôi buộc phải có những phân tích như trên.

Nhiều người cứ viết theo như họ hiểu nhưng không lưu ý. Nếu họ hiểu sai thì kệ bạn. Bạn không mô tả chính xác cho họ hiểu thì bạn tự lĩnh hậu quả. Nhưng tôi khi không hiểu thì tôi không thể viết được code. Nếu tôi cho là mình hiểu nhưng chưa dám chắc chắn thì tôi luôn lưu ý là code tôi đưa ra được viết cho giả thiết nào.
Cảm ơn Anh @batman1 đã xem code nhé.
Tôi thấy bạn ấy ghi là " ....sẽ lấy toàn bộ dữ liệu ở sheet summary đổ sang sheet historys từ A2 đến Y...." Do vậy tôi mới Dùng cách ghi lại (đổ sang) mảng Arr của Sh SUMMARY lên Sh History thế thôi. Cũng chẳng có công để đoán ý của bạn đó nữa.
Còn cái đoạn yêu cầu thay đổi thêm bớt dữ liệu của Sh SUMMARY và các sh khác mà không làm mất đi dữ liệu của Sh History đã được Refersh thì thực tình tôi cũng chỉ viết theo ý hiểu của mình và cũng đã test thử những không test kỹ được.

Người nhờ hỗ trợ phải mô tả chính xác yêu cầu mà họ mong muốn và khi đã được hỗ trợ thì phải test kỹ các kết quả theo từng yêu cầu rồi mới phản hồi là đã đáp ứng được nhu cầu của mình.
Anh viết "....Nhiều người cứ viết theo như họ hiểu nhưng không lưu ý. Nếu họ hiểu sai thì kệ bạn. Bạn không mô tả chính xác cho họ hiểu thì bạn tự lĩnh hậu quả. ....". Đúng thế, rất nhiều trường hợp người viết code theo ý đoán mò ý của người cần hỗ trợ. Tôi khi trả bài thường có lưu ý là phải thêm bớt dữ liệu và test thật kỹ, còn người ta test kỹ hay không kỹ (cũng như không mô ta chính xác yêu cầu) thì ....
 
Upvote 0
Cảm ơn Anh @batman1 đã xem code nhé.
Tôi thấy bạn ấy ghi là " ....sẽ lấy toàn bộ dữ liệu ở sheet summary đổ sang sheet historys từ A2 đến Y...." Do vậy tôi mới Dùng cách ghi lại (đổ sang) mảng Arr của Sh SUMMARY lên Sh History thế thôi. Cũng chẳng có công để đoán ý của bạn đó nữa.
Còn cái đoạn yêu cầu thay đổi thêm bớt dữ liệu của Sh SUMMARY và các sh khác mà không làm mất đi dữ liệu của Sh History đã được Refersh thì thực tình tôi cũng chỉ viết theo ý hiểu của mình và cũng đã test thử những không test kỹ được.

Người nhờ hỗ trợ phải mô tả chính xác yêu cầu mà họ mong muốn và khi đã được hỗ trợ thì phải test kỹ các kết quả theo từng yêu cầu rồi mới phản hồi là đã đáp ứng được nhu cầu của mình.
Anh viết "....Nhiều người cứ viết theo như họ hiểu nhưng không lưu ý. Nếu họ hiểu sai thì kệ bạn. Bạn không mô tả chính xác cho họ hiểu thì bạn tự lĩnh hậu quả. ....". Đúng thế, rất nhiều trường hợp người viết code theo ý đoán mò ý của người cần hỗ trợ. Tôi khi trả bài thường có lưu ý là phải thêm bớt dữ liệu và test thật kỹ, còn người ta test kỹ hay không kỹ (cũng như không mô ta chính xác yêu cầu) thì ....
Dạ em xin lỗi anh, đúng là do em chạy code vội vàng trả lời a ngay, trong khi a đã bỏ rất nhiều thời gian để giúp em, một phần em sợ nói sai hoặc nói làm a không hiểu lại bị mắng nên em cũng không biết diễn đạt sao nữa, lúc a bảo kết thúc em biết a đang không hài lòng, em cũng có nhiều điều muốn hỏi lại không dám hỏi nữa, em xin lỗi a nhé.
Bài đã được tự động gộp:

Về đoạn mà bạn hỏi trong đoạn trích ở trên thì ...
Bạn cần hiểu là ZAQ_historys có nghĩa là lấy vùng từ cột Z tới cột AQ của HISTORYS vào mảng ZAQ_historys. Vì thế không có chuyện ZAQ_historys = .Range("AA2:AS" & lastRow).Value - tức không có chuyện lấy từ cột AA tới AS vào mảng ZAQ_historys đâu.

Bạn để ý là trong mảng thong_tin sheet MATER_ITEM được đặt cuối cùng. Vì sao? Vì khi duyệt các sheet khác thì đều lấy SOL ở cột A của HISTOSYS để tìm trong cột A của sheet đang duyệt. Chỉ tới khi duyệt MATER_ITEM mới lấy ITEM từ cột L của HISTORYS để tìm trong cột A của MATER_ITEM. Vì thế khi duyệt các sheet khác thì ta luôn dùng chung 1 dic, chỉ khi duyệt tới giá trị cuối cùng của vòng FOR ta mới tạo dic mới để làm bảng dò cho MATER_ITEM. Chính vì thế khi thêm sheet thì không thể đặt sau MATER_ITEM được. Và nữa: hiện tại ta chỉ tìm cột A hoặc L của HISTORYS trong các sheet. Thế với sheet thêm thì tìm cột nào của HISTORYS trong sheet thêm? Nếu không là A mà cũng không là L thì còn sửa nữa, vì bảng dò (dic) cũng phải tạo khi duyệt sheet thêm. Tóm lại phải mô tả về sheet thêm này (cách duyệt, khi tìm thấy thì lấy những cột nào để làm mới HISTORYS ...) thì mới nói chuyện được.
--------------

Lẽ ra bạn nên hỏi HUONGHCKT. Theo tôi thì bạn mô tả một đằng còn HUONGHCKT làm một nẻo. Nhưng nếu bạn đổi ý và hài lòng với code đó thì đó là quyền của bạn.

Bạn phải tự test kỹ vì nếu không thì không có gì đảm bảo là code của bất kỳ ai đó cũng làm làm đúng yêu cầu của bạn.
Nếu bạn cuối cùng cho là code của HUONGHCKT chưa làm đúng yêu cầu của bạn thì bạn phải nói rõ ra và nhờ HUONGHCKT sửa lại. Cho tới tận giờ bạn không nói ra và nhờ sửa thì HUONGHCKT có quyền cho là code đã làm đúng yêu cầu của bạn.

Bạn nên nhờ tiếp HUONGHCKT vì code của tôi nếu có đúng thì cũng chỉ là code cho refresh All. Bây giờ đọc kỹ lại bài #1 tôi mới thấy


Cái phần này tôi chưa làm, nhưng tôi thấy HUONGHCKT đã làm cho bạn. Tôi không dám phán là đã đúng ý bạn vì thực ra tôi cũng chưa rõ yêu cầu này. Nhưng HUONGHCKT đã làm thì chỉ cần sửa thôi.

Về phần mình thì nếu thêm cả phần nói ở trên thì có lẽ tôi sẽ viết hơi khác một chút code để sao cho có thể dùng cho refresh All và cả cho cho phần trên. Nhưng tôi chưa hiểu yêu cầu. Tôi trích lại:


Giả sử MỘT DÒNG NÀO ĐÓ của MATER_ITEM thay đổi thì cách làm nào sau đây là đúng yêu cầu (có thể 2 cách đều cho kết quả như nhau ***):

a. tìm từng dữ liệu trong cột L của HISTORYS trong cột A của dòng THAY ĐỔI của MATER_ITEM (chỉ của MATER_ITEM vì không duyệt các sheet không có thay đổi? Đúng là thế hay thế nào?). Nếu không tìm thấy thì không làm gì. Nếu tìm thấy thì lấy dữ liệu tương ứng từ MATER_ITEM sang HISTORYS.

b. tìm từng dữ liệu trong cột L của HISTORYS trong TOÀN BỘ cột A của MATER_ITEM (chỉ của MATER_ITEM vì không duyệt các sheet không có thay đổi? Đúng là thế hay thế nào?). Nếu không tìm thấy thì không làm gì. Nếu tìm thấy thì lấy dữ liệu tương ứng từ MATER_ITEM sang HISTORYS.

Tương tự với các sheet khác. Bạn phải cho biết cách thao tác là theo a. hay b. Nếu thao tác theo b. luôn có thể chấp nhận được thì cũng nói rõ.

***: do tôi không biết dữ liệu trong các sheet xuất hiện và biến mất theo cách nào, qui luật nào nên tôi cho ví dụ khi cách duyệt a. và b. cho hậu quả khác nhau. Vd. hiện tại trong HISTORYS ở ô nào đó của cột L có giá trị 123456789. Trong MATER_ITEM đang có ở cột A giá trị 123456789, và E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ". Khi nhấn nút refresh All thì E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ" được lấy sang HISTORYS sang AM, AN, AO và cùng dòng với 123456789. Bây giờ trong sheet MATER_ITEM ngoài 123456789 đã có ta chèn thêm 1 dòng khác TRƯỚC NÓ có các dữ liệu khác nhau ở các cột khác nhưng ở cột A cũng có 123456789, và E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới". Nếu bây giờ tìm 123456789 lấy từ cột L của HISTORYS trong cột A của MATER_ITEM thì:

- nếu tìm theo cách a. thì kết quả là E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới" được nhập vào AM, AN, AO của HISTORYS và ghi đè lên "ngày mai cũ", "em đi cũ", "biển nhớ cũ".

- nếu tìm theo cách b. thì kết quả là: đầu tiên E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới" được nhập vào AM, AN, AO của HISTORYS (tìm thấy 123456789 ở dòng mới) và ghi đè lên E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ" đang có. Tiếp theo E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ" được nhập vào AM, AN, AO của HISTORYS (tìm thấy 123456789 ở dòng cũ) và ghi đè lên E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới" đang có ở thời điểm này. Kết quả có E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ"

Cách a. và b. cho kết quả khác nhau. Vì tôi không biết dữ liệu trong các sheet thoắt xuất hiện thoắt biến mất như thế nào, theo cách nào, qui luật nào nên tôi buộc phải có những phân tích như trên.

Nhiều người cứ viết theo như họ hiểu nhưng không lưu ý. Nếu họ hiểu sai thì kệ bạn. Bạn không mô tả chính xác cho họ hiểu thì bạn tự lĩnh hậu quả. Nhưng tôi khi không hiểu thì tôi không thể viết được code. Nếu tôi cho là mình hiểu nhưng chưa dám chắc chắn thì tôi luôn lưu ý là code tôi đưa ra được viết cho giả thiết nào.
Dạ, em sẽ sẽ đọc chi tiết tất cả nhưng gì a viết để hiểu cốt lõi vấn đề, sau đó em sẽ điều chỉnh lại code để thêm thử các sheet khác, có gì không hiểu em hỏi a giúp em nhé.
 
Upvote 0
Bạn hãy trích chính xác nhé. Muốn trả lời ai thì trích bài của người ấy. Trích bừa bãi thì khó đoán bạn định trả lời ai

Nhìn câu trả lời

lúc a bảo kết thúc em biết a đang không hài lòng,
thì có vẻ bạn đang viết cho tôi vì chỉ có tôi mới tuyên bố là "kết thúc". Thế thì tại sao lại trích bài của bạn HUONGHCKT? Mà đã trích thì trích đoạn mà mình định bình luận thôi chứ không phải trích cả bài.
Dạ, em sẽ sẽ đọc chi tiết tất cả nhưng gì a viết để hiểu cốt lõi vấn đề, sau đó em sẽ điều chỉnh lại code để thêm thử các sheet khác, có gì không hiểu em hỏi a giúp em nhé.
Hãy đọc kỹ bài #27 và trả lời những câu hỏi của tôi trong bài đó. Nếu tôi hiểu được thì tôi sẽ viết lại toàn bộ code cho bạn.
 
Upvote 0
Dạ em xin lỗi anh, đúng là do em chạy code vội vàng trả lời a ngay, trong khi a đã bỏ rất nhiều thời gian để giúp em, một phần em sợ nói sai hoặc nói làm a không hiểu lại bị mắng nên em cũng không biết diễn đạt sao nữa, lúc a bảo kết thúc em biết a đang không hài lòng, em cũng có nhiều điều muốn hỏi lại không dám hỏi nữa, em xin lỗi a nhé.
Bài đã được tự động gộp:


Dạ, em sẽ sẽ đọc chi tiết tất cả nhưng gì a viết để hiểu cốt lõi vấn đề, sau đó em sẽ điều chỉnh lại code để thêm thử các sheet khác, có gì không hiểu em hỏi a giúp em nhé.
Mà tôi có nói là kết thúc đâu nhỉ? Tôi tin là không ai mắng bạn đâu. Họ chỉ phật ý khi người cần trợ giúp có những biểu hiện thái độ thiếu tôn trọng (sắc màu văn hóa, văn minh thấp) mà thôi. Họ đã bỏ công ra giúp bạn nếu không vì cái đã nói trên thì hà cớ gì họ không giúp bạn tới cùng.
Bạn cứ hỏi cứ đăng lên, tôi tin là có rất nhiều người cũng quan tâm đến vấn đề bạn nêu, qua đó họ cũng đã có được chút ít nào đó vấn đề mà họ quan tâm.
 
Upvote 0
- nếu tìm theo cách a. thì kết quả là E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới" được nhập vào AM, AN, AO của HISTORYS và ghi đè lên "ngày mai cũ", "em đi cũ", "biển nhớ cũ".

- nếu tìm theo cách b. thì kết quả là: đầu tiên E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới" được nhập vào AM, AN, AO của HISTORYS (tìm thấy 123456789 ở dòng mới) và ghi đè lên E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ" đang có. Tiếp theo E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ" được nhập vào AM, AN, AO của HISTORYS (tìm thấy 123456789 ở dòng cũ) và ghi đè lên E,F, G = "ngày mai mới", "em đi mới", "biển nhớ mới" đang có ở thời điểm này. Kết quả có E, F, G = "ngày mai cũ", "em đi cũ", "biển nhớ cũ"
A batman1 ơi em đọc xong 2 ý này có thể hiểu được 2 ý a, b
em nói lại không biết đã đúng chưa, nghĩa là nếu sheet MASTER_ITEM có 2 dòng cột

A1 = 123456789, E1 = "ngày mai cũ" , F1 = "em đi cũ" , G1 = "biển nhớ cũ"
A2 = 123456789, E2 = "ngày mai mới" , F2 = "em đi mới" , G2 = "biển nhớ mới"

thì khi duyệt MASTER_ITEM sẽ lấy dòng nào đúng không anh? thực ra sheet MASTER_ITEM em sẽ chỉ để 1 dòng duy nhất thôi ạ, nếu có 2 dòng trở lên thì là do em copy bị trùng chưa loại đi, a có thể code theo ý a và b đều được ạ, áp dụng tương tự đối với các sheet khác có thể theo a hoặc b đều được.

Bạn cần hiểu là ZAQ_historys có nghĩa là lấy vùng từ cột Z tới cột AQ của HISTORYS vào mảng ZAQ_historys. Vì thế không có chuyện ZAQ_historys = .Range("AA2:AS" & lastRow).Value - tức không có chuyện lấy từ cột AA tới AS vào mảng ZAQ_historys đâu.

Bạn để ý là trong mảng thong_tin sheet MATER_ITEM được đặt cuối cùng. Vì sao? Vì khi duyệt các sheet khác thì đều lấy SOL ở cột A của HISTOSYS để tìm trong cột A của sheet đang duyệt. Chỉ tới khi duyệt MATER_ITEM mới lấy ITEM từ cột L của HISTORYS để tìm trong cột A của MATER_ITEM. Vì thế khi duyệt các sheet khác thì ta luôn dùng chung 1 dic, chỉ khi duyệt tới giá trị cuối cùng của vòng FOR ta mới tạo dic mới để làm bảng dò cho MATER_ITEM. Chính vì thế khi thêm sheet thì không thể đặt sau MATER_ITEM được. Và nữa: hiện tại ta chỉ tìm cột A hoặc L của HISTORYS trong các sheet. Thế với sheet thêm thì tìm cột nào của HISTORYS trong sheet thêm? Nếu không là A mà cũng không là L thì còn sửa nữa, vì bảng dò (dic) cũng phải tạo khi duyệt sheet thêm. Tóm lại phải mô tả về sheet thêm này (cách duyệt, khi tìm thấy thì lấy những cột nào để làm mới HISTORYS ...) thì mới nói chuyện được.

-> Dạ đúng như a nói phần sheet thêm mới cột dò tìm của sheet historys là A thì em dựa vào phần a ghi chú em đã thêm được một số sheet, nhưng đối với sheet thêm cần cột L để dò tìm thì em đang gặp rắc rối,
em đã thêm 1 sheet SPEED_MACHINE, điều kiện lấy là nếu tìm thấy cột L của historys bên cột B sheet SPEED_MACHINE thì lấy các cột E F G H I trả về vùng AV, AW, AX, AY, AZ sheet HISTORYS, nếu không tìm thấy thì không làm gì cả.
a có thể để code giúp em sao cho khi em cần thêm sheet tham chiều từ cột L em có thể tùy chỉnh để thêm được không ạ?

Trước a có nói cho em phần ngày tháng các cột C D E dữ liệu gốc nó không đúng em nghĩ mãi mới tìm ra giải pháp chuyển đổi bằng cách thêm cột chuyển đổi thành ngày tháng xịn, và đặt công thức trong bảng FRU nó sẽ tự động chạy, dữ liệu trong sheet historys sẽ lấy từ sheet FRU từ A->AB thay vì A-Y từ sheet summary như trước đó, summary cũng lấy từ FRU nên em chuyển qua lấy trực tiếp từ FRU luôn.
vì vậy khi a xem file đính kèm sẽ hơi khác một chút.

-> Đối với sheet summary cái này trước em đi nhặt nhạnh code để sửa nhưng đến giờ khi cần thêm sheet SPEED_MACHINE Lấy cột L của summary để dò tìm thì cũng không còn chạy được nữa, em có lấy toàn bộ code của historys sang chạy thử, sheet summary cách hoạt động giống hệt nhưng sheets historys chỉ khác là không lưu trữ lịch sử, em thử đưa dòng này vào Sheets("SUMMARY").Range("A2:AZ20000").ClearContents, nhưng code báo lỗi
trên dòng này
ThisWorkbook.Worksheets("SUMMARY").Range("A2").Resize(UBound(AY_historys, 1), UBound(AY_historys, 2)).Value = AY_historys
em đang hiểu lỗi này là do không có dòng nào được thêm trước vào summary nên gây ra lỗi, nên a xem giúp em với
sheet summary sẽ lấy dữ liệu từ A-AB bên sheet FRU, sau đó cập nhật thông tin từ các sheet khác hoạt động giống hệt như historys chỉ khác là không lưu lịch sử.

-> Em còn 2 thỉnh cầu nữa thôi
mặc dù nó không có trong mô tả lúc đầu vì khi làm mới phát sinh nên em rất cần a hỗ trợ, lúc a nói
***: do tôi không biết dữ liệu trong các sheet xuất hiện và biến mất theo cách nào, qui luật nào
em mới nhớ ra dữ liệu bên sheet summary và FRU em sẽ mất đi khi cột S chuyển trạng thái AWAITING_SHIPPING và AWAITING_FULFILLMENT sẽ biến mất trong vòng 24 đến 48 giờ vì vậy a có thể thêm giúp em tại cột BC của sheet HISTORYS sẽ ghi lại thời gian mỗi khi cột S chuyển trạng thái AWAITING_SHIPPING và WAITING_FULFILLMENT,

ví dụ khi nhấn vào refresh all, hôm nay 25 tháng 12 có 5 SOL ở cột A có 2 trạng thái ở cột S là AWAITING_SHIPPING và AWAITING_FULFILLMENT thì lấy ngày 25 tháng 12 điền vào dòng tương ứng của cột BC,
ngày mai 26-DEC có thêm 10 SOL ở cột A có 2 trạng thái ở cột S là AWAITING_SHIPPING và AWAITING_FULFILLMENT thì lấy ngày 26 tháng 12 điền vào dòng tương ứng của cột BC, như vậy em sẽ biết được mỗi ngày có thêm bao nhiêu SOL ở cột A chuyển trạng thái AWAITING_SHIPPING và AWAITING_FULFILLMENT.

- công thức ở cột BA và BB của 2 sheet summary, em thường phải kéo thủ công và rất hay bị loạn chồng chéo ô với nhau khiến kết quả bị sai lệch, ví dụ em kéo khoảng 10000 dòng thì không sao, em kéo đến 30000 dòng là excel báo Notresponding và tự đóng file, sau khi mở lại công thức không còn đúng với các ô đã được định như lúc đầu nữa mà nó nhảy loạn xạ, vì 2 cột BA và BB luôn luôn sẽ có thay đổi về giá trị trả về nên em ko copy value được
a có thể có cách nào giải quyết giúp em không ạ, liệu có code nào thay thế được công thức không a, hoặc mỗi lần sheet có số dòng đến đâu công thức sẽ tự động chạy tương ứng đến dòng đó.
 

File đính kèm

Upvote 0
Mà tôi có nói là kết thúc đâu nhỉ? Tôi tin là không ai mắng bạn đâu. Họ chỉ phật ý khi người cần trợ giúp có những biểu hiện thái độ thiếu tôn trọng (sắc màu văn hóa, văn minh thấp) mà thôi. Họ đã bỏ công ra giúp bạn nếu không vì cái đã nói trên thì hà cớ gì họ không giúp bạn tới cùng.
Bạn cứ hỏi cứ đăng lên, tôi tin là có rất nhiều người cũng quan tâm đến vấn đề bạn nêu, qua đó họ cũng đã có được chút ít nào đó vấn đề mà họ quan tâm.
Dạ em đã chạy thử rồi em thấy có một số vấn đề

em chạy phần NapDic trước nhưng không lấy được dữ liệu mới từ A đến Y, từ sheet summary vào sheet historys, chỉ chạy đúng lần nhấn nút refresh đầu tiên thôi, còn sau khi em thử thêm mới vào cột A vào sheet summary thì historys cũng không lấy được, phần cập nhật thay đổi từ B, C, D, E cũng chưa thấy có dữ liệu
dữ liệu sheet historys không được bảo toàn khi summary mất đi.

- phần cập nhật từ sheet master_item cũng không chạy,
- Nếu em muốn thêm sheet mới sử dụng cột L sheet historys tìm kiếm giá trợ tương ứng ở cột B SPEED lấy các cột E,F,G,H,I trả về các vùng AR, AS, AT, AU, AV em mở code em không biết sửa

a xem giúp em nhé, xong em sẽ chạy thử và kiểm tra tiếp ạ
 

File đính kèm

Upvote 0
Tôi đã viết cho bạn rồi. Các sheet khác SUMMARY ngoài việc duyệt trong refresh all thì mỗi sheet đó còn được duyệt khi có sự thay đổi trong chúng. Vì thế tôi sẽ viết lại hoàn toàn code, bạn không nên trích code cũ làm gì.

Có một điều bạn phải nói rõ khi những thống nhất tới thời điểm này lại bị thay đổi. Tới thời điểm này ta thống nhất là khi nhấn refresh all thì: duyệt SUMMARY và một số sheet khác. Bây giờ hình như là không duyệt SUMMARY nữa mà duyệt FRU. Nếu là thế thì phải khẳng định thật rõ, phải nhấn thật mạnh để tôi biết. Tôi xem qua thì ngoài việc duyệt FRU thay cho duyệt SUMMARY thì chi tiết cũng có thay đổi. Tức khi gặp dữ liệu đã có thì ngoài làm mới B:E và S còn làm mới mới K, Y và Z. Ngoài ra khi có dữ liệu mới thì không bê A:Y sang HISTORYS mà bê A:AB sang HISTORYS. Nếu đúng thế thì phải nói ra, nói thật to để người khác biết. Còn vấn đề nữa là code vẫn coi "dữ liệu mới" là khi CHỈ A mới (SOL mới). Có nghĩa là bạn không cho là dữ liệu mới khi A & B & C & ... & Y mới nữa à? Hay vẫn là CẢ DÒNG mới? À mà CẢ DÒNG bây giờ vẫn là A:Y hay bây giờ là A:AB hay A:AZ? A:AZ có lẽ là không vì tôi nhìn FRU chỉ có dữ liệu tới AE.

Khi mọi thứ lại thay đổi so với những gì đã thống nhất với nhau thì bạn phải nói ra, và nói thật rõ thật to. Nếu tôi không hiểu thì tôi không giúp bạn đâu.

ThisWorkbook.Worksheets("SUMMARY").Range("A2").Resize(UBound(AY_historys, 1), UBound(AY_historys, 2)).Value = AY_historys
em đang hiểu lỗi này là do không có dòng nào được thêm trước vào summary nên gây ra lỗi, nên a xem giúp em với
sheet summary sẽ lấy dữ liệu từ A-AB bên sheet FRU, sau đó cập nhật thông tin từ các sheet khác hoạt động giống hệt như historys chỉ khác là không lưu lịch sử.
không lưu lịch sử có nghĩa là gì? Bạn làm chuyên môn của mình thì bạn biết "lịch sử" nó là gì chứ tôi làm gì biết. Cũng như bạn nói "lấy nợ cũ" đối chiếu với ... thì tôi không làm chuyên môn kế toán làm sao tôi biết nợ cũ nó là cái gì. Nói với người ngoài thì phải nó: "lấy giá trị ở cột E" hoặc "lấy giá trị ở E7" chứ "nợ cũ", "lịch sử" thì đứa ít học như tôi biết nó là cái gì. Khi dùng khái niệm không phổ biến thì phải định nghĩa để người khác biết nó là gì.

tại cột BC của sheet HISTORYS sẽ ghi lại thời gian mỗi khi cột S chuyển trạng thái AWAITING_SHIPPING và WAITING_FULFILLMENT,
Tôi không hiểu.
Bạn viết là "khi cột S chuyển trạng thái AWAITING_SHIPPING và WAITING_FULFILLMENT". Với tôi thì phải viết:
- hoặc "khi cột S chuyển TỪ trạng thái ... SANG trạng thái ..."
- hoặc "khi cột S chuyển SANG trạng thái ...", đồng nghĩa với "khi cột S chuyển TỪ trạng thái BẤT KỲ SANG trạng thái ..."

Với tôi "khi cột S chuyển trạng thái AWAITING_SHIPPING và WAITING_FULFILLMENT" là không rõ ràng. Vì nó có nghĩa là "TỪ AWAITING_SHIPPING hoặc WAITING_FULFILLMENT" (SANG bất kỳ) hay là "SANG AWAITING_SHIPPING hoặc WAITING_FULFILLMENT" (TỪ bất kỳ)?

Liệu có phải bạn định viết: "khi cột S chuyển SANG trạng thái AWAITING_SHIPPING hoặc WAITING_FULFILLMENT"? Có nghĩa là không quan trọng từ trạng thái nào, miễn SANG trạng thái AWAITING_SHIPPING hoặc WAITING_FULFILLMENT thì đều ghi chú?

ví dụ khi nhấn vào refresh all, hôm nay 25 tháng 12 có 5 SOL ở cột A có 2 trạng thái ở cột S là AWAITING_SHIPPING và AWAITING_FULFILLMENT thì lấy ngày 25 tháng 12 điền vào dòng tương ứng của cột BC,
Nếu bạn đã lấy ví dụ thì nên giúp người ta khỏi dò tìm mất công. Thay vì
ví dụ khi nhấn vào refresh all, hôm nay 25 tháng 12 có 5 SOL ở cột A có 2 trạng thái ở cột S là AWAITING_SHIPPING và AWAITING_FULFILLMENT thì lấy ...
Thì nên viết
ví dụ khi nhấn vào refresh all, hôm nay 25 tháng 12 có 5 SOL ở cột A là 61520066-24, 61520066-25, 61520066-26, 61520066-27, 61520066-28 có ở cột S trạng thái ... TRƯỚC KHI NHẤN Referesh All và trạng thái SAU KHI NHẤN Refresh All là AWAITING_SHIPPING và AWAITING_FULFILLMENT thì lấy ...
 
Upvote 0
Tôi đã viết cho bạn rồi. Các sheet khác SUMMARY ngoài việc duyệt trong refresh all thì mỗi sheet đó còn được duyệt khi có sự thay đổi trong chúng. Vì thế tôi sẽ viết lại hoàn toàn code, bạn không nên trích code cũ làm gì.

Có một điều bạn phải nói rõ khi những thống nhất tới thời điểm này lại bị thay đổi. Tới thời điểm này ta thống nhất là khi nhấn refresh all thì: duyệt SUMMARY và một số sheet khác. Bây giờ hình như là không duyệt SUMMARY nữa mà duyệt FRU. Nếu là thế thì phải khẳng định thật rõ, phải nhấn thật mạnh để tôi biết. Tôi xem qua thì ngoài việc duyệt FRU thay cho duyệt SUMMARY thì chi tiết cũng có thay đổi. Tức khi gặp dữ liệu đã có thì ngoài làm mới B:E và S còn làm mới mới K, Y và Z. Ngoài ra khi có dữ liệu mới thì không bê A:Y sang HISTORYS mà bê A:AB sang HISTORYS. Nếu đúng thế thì phải nói ra, nói thật to để người khác biết. Còn vấn đề nữa là code vẫn coi "dữ liệu mới" là khi CHỈ A mới (SOL mới). Có nghĩa là bạn không cho là dữ liệu mới khi A & B & C & ... & Y mới nữa à? Hay vẫn là CẢ DÒNG mới? À mà CẢ DÒNG bây giờ vẫn là A:Y hay bây giờ là A:AB hay A:AZ? A:AZ có lẽ là không vì tôi nhìn FRU chỉ có dữ liệu tới AE.

Khi mọi thứ lại thay đổi so với những gì đã thống nhất với nhau thì bạn phải nói ra, và nói thật rõ thật to. Nếu tôi không hiểu thì tôi không giúp bạn đâu.


không lưu lịch sử có nghĩa là gì? Bạn làm chuyên môn của mình thì bạn biết "lịch sử" nó là gì chứ tôi làm gì biết. Cũng như bạn nói "lấy nợ cũ" đối chiếu với ... thì tôi không làm chuyên môn kế toán làm sao tôi biết nợ cũ nó là cái gì. Nói với người ngoài thì phải nó: "lấy giá trị ở cột E" hoặc "lấy giá trị ở E7" chứ "nợ cũ", "lịch sử" thì đứa ít học như tôi biết nó là cái gì. Khi dùng khái niệm không phổ biến thì phải định nghĩa để người khác biết nó là gì.


Tôi không hiểu.
Bạn viết là "khi cột S chuyển trạng thái AWAITING_SHIPPING và WAITING_FULFILLMENT". Với tôi thì phải viết:
- hoặc "khi cột S chuyển TỪ trạng thái ... SANG trạng thái ..."
- hoặc "khi cột S chuyển SANG trạng thái ...", đồng nghĩa với "khi cột S chuyển TỪ trạng thái BẤT KỲ SANG trạng thái ..."

Với tôi "khi cột S chuyển trạng thái AWAITING_SHIPPING và WAITING_FULFILLMENT" là không rõ ràng. Vì nó có nghĩa là "TỪ AWAITING_SHIPPING hoặc WAITING_FULFILLMENT" (SANG bất kỳ) hay là "SANG AWAITING_SHIPPING hoặc WAITING_FULFILLMENT" (TỪ bất kỳ)?

Liệu có phải bạn định viết: "khi cột S chuyển SANG trạng thái AWAITING_SHIPPING hoặc WAITING_FULFILLMENT"? Có nghĩa là không quan trọng từ trạng thái nào, miễn SANG trạng thái AWAITING_SHIPPING hoặc WAITING_FULFILLMENT thì đều ghi chú?


Nếu bạn đã lấy ví dụ thì nên giúp người ta khỏi dò tìm mất công. Thay vì

Thì nên viết
-Bây giờ hình như là không duyệt SUMMARY nữa mà duyệt FRU. Nếu là thế thì phải khẳng định thật rõ, phải nhấn thật mạnh để tôi biết -> chỗ này em chưa nhấn mạnh rõ ràng-> em xác nhận là lấy từ sheet FRU a nhé

-Tôi xem qua thì ngoài việc duyệt FRU thay cho duyệt SUMMARY thì chi tiết cũng có thay đổi. Tức khi gặp dữ liệu đã có thì ngoài làm mới B:E và S còn làm mới mới K, Y và Z-> chính xác ạ

-Ngoài ra khi có dữ liệu mới thì không bê A:Y sang HISTORYS mà bê A:AB sang HISTORYS -> chính xác ạ

-dữ liệu mới" là khi CHỈ A mới (SOL mới). Có nghĩa là bạn không cho là dữ liệu mới khi A & B & C & ... & Y mới nữa à? Hay vẫn là CẢ DÒNG mới? -> cả dòng mới ạ
À mà CẢ DÒNG bây giờ vẫn là A:Y hay bây giờ là A:AB hay A:AZ? A:AZ có lẽ là không vì tôi nhìn FRU chỉ có dữ liệu tới AE. -> cả dòng mới là A:AB, vì từ AC đến AE ngày cột ngày tháng định dạng không chuẩn nên không cần lấy thêm AC-AE nữa

- không lưu lịch sử có nghĩa là gì? Bạn làm chuyên môn của mình thì bạn biết "lịch sử" nó là gì chứ tôi làm gì biết.-> không lưu trữ lịch sử ở đây nghĩa là sheet FRU sẽ mất dữ liệu theo thời gian thì sheet summary cũng sẽ mất theo
ví dụ hôm nay 25 tháng 12 SOL 57038842-1 ở A2 kèm theo các giá trị khác nằm ở B2,C2 cho đến AB2 đang nằm ở sheet FRU khi nhấn refresh all sẽ cập nhật sang sheet summary từ A2 đến AB2 và lấy thêm dữ liệu từ các sheet khác bắt đầu từ cột AC2 đến AZ2 dựa trên cột cần dò tìm là cột A và cột L, sang ngày 26 hoặc 27 SOL 57038842-1 ở cột A2 kèm theo các giá trị khác nằm ở B2,C2 cho đến AB2 không còn tồn tại ở sheet FRU nữa, thì sheet summary cũng sẽ bị mất đi dòng A2 đến AZ2.

nó khác so với sheet historys ví dụ

hôm nay 25 tháng 12 SOL 57038842-1 ở A2 kèm theo các giá trị khác nằm ở B2,C2 cho đến AB2 đang nằm ở sheet FRU khi nhấn refresh all sẽ cập nhật sang sheet historys từ A2 đến AB2 và lấy thêm dữ liệu từ các sheet khác bắt đầu từ cột AC2 đến AZ2 dựa trên cột cần dò tìm là cột A và cột L, sang ngày 26 hoặc 27 SOL 57038842-1 ở cột A2 kèm theo các giá trị khác nằm ở B2,C2 cho đến AB2 không còn tồn tại ở sheet FRU nữa thì sheet historys sẽ không bị mất đi dòng A2 đến AZ2.



Nếu bạn đã lấy ví dụ thì nên giúp người ta khỏi dò tìm mất công. Thay vì
ví dụ khi nhấn vào refresh all, hôm nay 25 tháng 12 có 5 SOL ở cột A có 2 trạng thái ở cột S là AWAITING_SHIPPING và AWAITING_FULFILLMENT thì lấy ...
Thì nên viết
ví dụ khi nhấn vào refresh all, hôm nay 25 tháng 12 có 5 SOL ở cột A là 61520066-24, 61520066-25, 61520066-26, 61520066-27, 61520066-28 có ở cột S trạng thái
PRODUCTION_OPEN
EXTERNAL_REQ_OPEN
SUPPLY_ELIGIBLE
ENTERED
PO_OPEN
BOOKED
TRƯỚC KHI NHẤN Referesh All và trạng thái SAU KHI NHẤN Refresh All là AWAITING_SHIPPING và AWAITING_FULFILLMENT thì lấy ngày 25 tháng 12 điền vào cột BC,

Liệu có phải bạn định viết: "khi cột S chuyển SANG trạng thái AWAITING_SHIPPING hoặc WAITING_FULFILLMENT"? Có nghĩa là không quan trọng từ trạng thái nào, miễn SANG trạng thái AWAITING_SHIPPING hoặc WAITING_FULFILLMENT thì đều ghi chú? -> chính xác anh nhé

em xin lỗi đã để a phải đoán nhiều phần em giải thích chưa rõ ràng, cũng may mắn cho em là a đoán đều chính xác thậm chí phân tích rất chi tiết các tình huống có thể gây sai dữ liệu.
 
Upvote 0
- không lưu lịch sử có nghĩa là gì? Bạn làm chuyên môn của mình thì bạn biết "lịch sử" nó là gì chứ tôi làm gì biết.-> không lưu trữ lịch sử ở đây nghĩa là sheet FRU sẽ mất dữ liệu theo thời gian thì sheet summary cũng sẽ mất theo
ví dụ hôm nay 25 tháng 12 SOL 57038842-1 ở A2 kèm theo các giá trị khác nằm ở B2,C2 cho đến AB2 đang nằm ở sheet FRU khi nhấn refresh all sẽ cập nhật sang sheet summary từ A2 đến AB2 và lấy thêm dữ liệu từ các sheet khác bắt đầu từ cột AC2 đến AZ2 dựa trên cột cần dò tìm là cột A và cột L, sang ngày 26 hoặc 27 SOL 57038842-1 ở cột A2 kèm theo các giá trị khác nằm ở B2,C2 cho đến AB2 không còn tồn tại ở sheet FRU nữa, thì sheet summary cũng sẽ bị mất đi dòng A2 đến AZ2.

nó khác so với sheet historys ví dụ

hôm nay 25 tháng 12 SOL 57038842-1 ở A2 kèm theo các giá trị khác nằm ở B2,C2 cho đến AB2 đang nằm ở sheet FRU khi nhấn refresh all sẽ cập nhật sang sheet historys từ A2 đến AB2 và lấy thêm dữ liệu từ các sheet khác bắt đầu từ cột AC2 đến AZ2 dựa trên cột cần dò tìm là cột A và cột L, sang ngày 26 hoặc 27 SOL 57038842-1 ở cột A2 kèm theo các giá trị khác nằm ở B2,C2 cho đến AB2 không còn tồn tại ở sheet FRU nữa thì sheet historys sẽ không bị mất đi dòng A2 đến AZ2.
Tóm lại là khi nhấn Refresh All:

1. Duyệt FRU cho HISTORYS
a. kiểm tra từng dòng (A & B & ... & AB) của FRU có xuất hiện trong HISTORYS hay không. Nếu đã có thì làm mới B:E, S, K, Y và Z. Nếu chưa có thì thêm dòng đó vào cuối HISTORYS.
b. duyệt các sheet SHIPOUT, MATER_ITEM, ...

2. Duyệt FRU cho SUMMARY
a. kiểm tra từng dòng (A & B & ... & AB) của FRU có xuất hiện trong SUMMARY hay không. Nếu đã có thì làm mới B:E, S, K, Y và Z. Nếu chưa có thì thêm dòng đó vào cuối SUMMARY.
b. duyệt các sheet SHIPOUT, MATER_ITEM, ...
c. nếu có dòng nào đó trong SUMMARY mà không xuất hiện trong FRU thì xóa dòng đó khỏi SUMMARY.

Tức duyệt 2 sheet HISTORYS và SUMMARY khác nhau ở chỗ khi duyệt SUMMARY thì làm thêm thao tác c.? Nếu thế thì xóa là xóa dữ liệu và để dòng trống hay xóa nghĩa là DELETE dòng và các dòng ở dưới dồn lên?

Nếu có thời gian thì hôm nay tôi sẽ thử viết, ngược lại thì phải ngày mai.

À còn một ý nữa là ngoài chạy code khi nhấn Refresh All thì cũng chạy một code khác khi một trong các sheet SHIPOUT, MATER_ITEM, ... thay đổi, tức khi đó cũng duyệt nó cho HISTORYS. Vậy khi đó có duyệt nó cho cả SUMMARY hay không?
 
Lần chỉnh sửa cuối:
Upvote 0
Tóm lại là khi nhấn Refresh All:

1. Duyệt FRU cho HISTORYS
a. kiểm tra từng dòng (A & B & ... & AB) của FRU có xuất hiện trong HISTORYS hay không. Nếu đã có thì làm mới B:E, S, K, Y và Z. Nếu chưa có thì thêm dòng đó vào cuối HISTORYS.
b. duyệt các sheet SHIPOUT, MATER_ITEM, ...

2. Duyệt FRU cho SUMMARY
a. kiểm tra từng dòng (A & B & ... & AB) của FRU có xuất hiện trong SUMMARY hay không. Nếu đã có thì làm mới B:E, S, K, Y và Z. Nếu chưa có thì thêm dòng đó vào cuối SUMMARY.
b. duyệt các sheet SHIPOUT, MATER_ITEM, ...
c. nếu có dòng nào đó trong SUMMARY mà không xuất hiện trong FRU thì xóa dòng đó khỏi SUMMARY.

Tức duyệt 2 sheet HISTORYS và SUMMARY khác nhau ở chỗ khi duyệt SUMMARY thì làm thêm thao tác c.? Nếu thế thì xóa là xóa dữ liệu và để dòng trống hay xóa nghĩa là DELETE dòng và các dòng ở dưới dồn lên?

Nếu có thời gian thì hôm nay tôi sẽ thử viết, ngược lại thì phải ngày mai.

À còn một ý nữa là ngoài chạy code khi nhấn Refresh All thì cũng chạy một code khác khi một trong các sheet SHIPOUT, MATER_ITEM, ... thay đổi, tức khi đó cũng duyệt nó cho HISTORYS. Vậy khi đó có duyệt nó cho cả SUMMARY hay không?
phần tóm tắt 1 và 2 a vừa liệt kê là chính xác a nhé.

Tức duyệt 2 sheet HISTORYS và SUMMARY khác nhau ở chỗ khi duyệt SUMMARY thì làm thêm thao tác c.? Nếu thế thì xóa là xóa dữ liệu và để dòng trống hay xóa nghĩa là DELETE dòng và các dòng ở dưới dồn lên? -> dạ xóa hẳn dòng và dồn các dòng ở dưới lên ạ

À còn một ý nữa là ngoài chạy code khi nhấn Refresh All thì cũng chạy một code khác khi một trong các sheet SHIPOUT, MATER_ITEM, ... thay đổi, tức khi đó cũng duyệt nó cho HISTORYS. Vậy khi đó có duyệt nó cho cả SUMMARY hay không?-> duyệt luôn cả sheet summary ạ, hoặc a để giúp em 2 nút ở 2 sheet summary và historys khi cần cập nhật sheet nào em nhấn sheet đó cũng được, vì em sợ gộp một lúc code sẽ chạy lâu anh ạ.

Nếu có thời gian thì hôm nay tôi sẽ thử viết, ngược lại thì phải ngày mai.-> vâng hôm nay hoặc mai a viết giúp em cũng được
 
Upvote 0
Dạ em đã chạy thử rồi em thấy có một số vấn đề

em chạy phần NapDic trước nhưng không lấy được dữ liệu mới từ A đến Y, từ sheet summary vào sheet historys, chỉ chạy đúng lần nhấn nút refresh đầu tiên thôi, còn sau khi em thử thêm mới vào cột A vào sheet summary thì historys cũng không lấy được, phần cập nhật thay đổi từ B, C, D, E cũng chưa thấy có dữ liệu
dữ liệu sheet historys không được bảo toàn khi summary mất đi.

- phần cập nhật từ sheet master_item cũng không chạy,
- Nếu em muốn thêm sheet mới sử dụng cột L sheet historys tìm kiếm giá trợ tương ứng ở cột B SPEED lấy các cột E,F,G,H,I trả về các vùng AR, AS, AT, AU, AV em mở code em không biết sửa

a xem giúp em nhé, xong em sẽ chạy thử và kiểm tra tiếp ạ
Tôi vẫn làm trên ý tưởng ban đầu.
1/Và chỉ giải quyết:
1.1 Bạn không cần phải chạy NapDic nữa vì khi mở Workbook ra là đã chạy NapDic rồi( sự kiện Workbook_Open ở ThisWorkbook).
1.2 code NapDic chỉ nạp dic cho các lần cập nhật sau (ví dụ cập nhật thêm ở Sh SUMMARY và các Sh khác). Do vậy nó sẽ không Đổ Từ Sh SUMMARY sang Sh History (từ A2: Y&dòng cuối= mảng Arr)
Code RefershAll sẽ có phần:
+ Đổ Từ Sh SUMMARY sang Sh History (từ A2: Y&dòng cuối= mảng Arr) - theo như ý ban đầu của bài #1
+ dò tìm cột A (SOL) hay Arr(i,1) của các Sh bạn muốn tham chiếu vào (như bài 2# đã giải thích) nếu thấy có trong Dic thì lấy các dữ liệu tương ứng và Gán vào Sh History theo đúng dòng và cột tương ứng. (Code History2 trong modul Import_Sh)
2/ Tất nhiên khi bạn làm thì có lẽ chỉ chạy modul Refersh All một lần đầu còn từ đó về sau cứ khi Sh SUMMARY có sự biến động (ở đây biến động là thêm dữ liệu-Bản ghi cuối cùng của Sh SUMMARY) thì Sh History sẽ được cập nhật thêm sự biến động ấy. Do khi bạn nhập liệu thì thông thường sẽ nhập từ cột A, B, C,... cho đến cuối cùng (cột Y), Do vậy, để ghi lại sự biến động của dòng cuối Sh SUM tôi sử dụng code bắt sự kiện ở Sh SUM.
Còn sự biến động của các Sh có thế ở bất kỳ bản ghi nào. Khi có sự biến động ấy code ở Sh ấy sẽ kích hoạt Sub History2 chạy để cho kết quả ở Sh History.
Riêng Sh Master _Item thì khi có biến động sẽ kích hoạt code NapDic hoạt động, và sau đó là kích hoạt Code History2 (modul Import_Sh) hoạt động.
Trong trường hợp bạn muốn thêm dữ liệu cho Sh History từ một Sh nào đó (ngoài những Sh được kể tên ở bài 2 ) thì phải sửa lại code

Sau khi đã chạy modul Refersh All rồi, bạn có thể Sửa lại, hoặc xóa các bản ghi của Sh SUMMARY thì Sh History cũng không bị sửa hoặc xóa.

Quy trình Test file của tôi làm như sau:
a/ Thủ xem Napdic có nạp sau khi mở file không và code History có hoạt động đúng không.?
Mở file lên. Vào Sh History(Thu). xóa sạch dữ liệu. Ghi lại và thoát file.
Mở lại file lên. vào Sh History(thu). nhấn nút Refersh All và xem kết quả. Kiểm tra dữ liệu được lấy ở các Sh khác vào xem có đúng không?-Kiểm tra thật kỹ nhé.
Ghi nhớ dòng cuối của Sh History(thu), sau đó thử vào sh SUM Copy một dòng bất kỳ (copy từ A đến X) sau đó gõ một vài ký tự bất kỳ vào Ô Y cùng dòng, và Enter. Chuyến sang Sh History(thu) và xem dữ liệu mới - Kể cả dữ liệu được lấy từ các Sh khác đã được thêm vào dòng cuối của Sh History(thu) chưa.

b/ Kiểm tra sự biến động của các Sh khác( các Sh được lấy dữ liệu cho Sh History(thu)-trừ Sh Master_Item))
Vào một Sh và thử thay đổi(Thêm bớt ký tự, hoặc xóa..) và enter. sau đó quay về Sh History(thu) để kiểm tra. (để đỡ mất công tìm kiếm- bạn nên chọn dòng có SOL trùng với SOL ở dòng 2-5 của sh Histor(thu).

c/ Kiểm tra sự biến động của các Sh Master_Item.
Vào một Sh và thử thay đổi(Thêm bớt ký tự, hoặc xóa, hoặc thêm Item mới...)ở bất kỳ dòng nào có số cột <5 và enter. sau đó quay về Sh History(thu) để kiểm tra.

Đây là cách tôi làm theo đúng ý tưởng của bạn trình bày ở bài 1 và bài 2. Cũng nói thật là dữ liệu của bạn nhiều( trên 5000 bản ghi), các trường (tên cột) lại là tiếng Tây, nên tôi cũng ngại kiểm tra kỹ. nhưng vẫn tin tưởng và thấy rằng chạy code không vấp lỗi và cho ra kết quả đúng như ý định viết code. Còn các ý tưởng của bạn phát sinh sau này, hoặc code của tôi cho ra kết quả chưa đúng ý, thì thực tình khuyên bạn nên trình bày thật kỹ với Anh @batman1, anh ấy sẽ nhiệt tình giúp bạn đến tận gốc vấn đề. Code anh ấy viết thì khỏi phải lo lắng gì về độ chính xác và tốc độ xử lý, kể cả các trường hợp phát sinh mà chính bạn cũng không lường hết được.

Cũng rất mong là bạn đọc hết và đọc kỹ bài viết này.

Bạn xem file đính kèm và chạy thử như cách tôi đã trình bày ở trên nhé.
Ngóng chờ hồi âm.
 

File đính kèm

Upvote 0
Code được viết với giả thiết sau đây:
1. Khi nhấn RefreshAll thì thực hiện code sub RefreshAll

a. Duyệt FRU để cập nhật HISTORYS và SUMMARY. Sub RefreshAll sẽ gọi sub duyet_FRU 2 lần để cập nhật HISTORYS và SUMMARY.
- kiểm tra từng dòng (A & B & ... & AB) của FRU có xuất hiện trong HISTORYS hoặc SUMMARY hay không. Nếu đã có thì làm mới B:E, S, K, Y và Z. Nếu chưa có thì thêm dòng đó vào cuối HISTORYS hoặc SUMMARY

- nếu dòng (A & B & ... & AB) nào đó của SUMMARY không có trong FRU thì xóa khỏi SUMMARY

b. Sub RefreshAll cũng gọi sub duyet_KHAC nhiều lần, mỗi lần để duyệt từng sheet SHIPOUT, MATER_ITEM, ... để cập nhật HISTORYS và SUMMARY

2. Trong sub duyet_KHAC do muốn rút gọn code nên tôi có đoạn
Mã:
'    cot_historys
    Select Case sheet_can_duyet_name
        Case "SHIPOUT", "ORDER_SCAN", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL", "MATERIAL_SHORTAGE", "BCNK": cot_historys = "A"
        Case "MATER_ITEM": cot_historys = "L"
    End Select
'    cot_do
    Select Case sheet_can_duyet_name
        Case "SHIPOUT", "ORDER_SCAN", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL", "MATER_ITEM": cot_do = "A"
        Case "MATERIAL_SHORTAGE", "BCNK": cot_do = "B"
    End Select
'    kq_tu_cot
    Select Case sheet_can_duyet_name
        Case "SHIPOUT", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL": kq_tu_cot = "B"
        Case "ORDER_SCAN", "BCNK": kq_tu_cot = "C"
        Case "MATERIAL_SHORTAGE": kq_tu_cot = "N"
        Case "MATER_ITEM": kq_tu_cot = "E"
    End Select
'    socot_kq
    Select Case sheet_can_duyet_name
        Case "SHIPOUT", "BCNK": socot_kq = 2
        Case "ORDER_SCAN", "BY_DATE", "KITTING", "MATERIAL_SHORTAGE", "SOL_CANCEL": socot_kq = 1
        Case "PRINT_STAGE", "CUT_STAGE", "MATER_ITEM": socot_kq = 3
    End Select
'    kq_den_cot
    Select Case sheet_can_duyet_name
        Case "SHIPOUT": kq_den_cot = 1
        Case "ORDER_SCAN": kq_den_cot = 3
        Case "BY_DATE": kq_den_cot = 17
        Case "KITTING": kq_den_cot = 4
        Case "MATERIAL_SHORTAGE": kq_den_cot = 5
        Case "PRINT_STAGE": kq_den_cot = 6
        Case "CUT_STAGE": kq_den_cot = 9
        Case "BCNK": kq_den_cot = 12
        Case "SOL_CANCEL": kq_den_cot = 18
        Case "MATER_ITEM": kq_den_cot = 14
    End Select

Nếu bạn cảm thấy khó hiểu thì thay toàn bộ đoạn trên bằng
Mã:
Select Case sheet_can_duyet_name
    Case "SHIPOUT":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 2
        kq_den_cot = 1
    Case "BY_DATE":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 1
        kq_den_cot = 17
    Case "KITTING":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 1
        kq_den_cot = 4
    Case "PRINT_STAGE":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 3
        kq_den_cot = 6
    Case "CUT_STAGE":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 3
        kq_den_cot = 9
    Case "SOL_CANCEL":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 1
        kq_den_cot = 18
    Case "ORDER_SCAN":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "C"
        socot_kq = 1
        kq_den_cot = 3
    Case "BCNK":
        cot_historys = "A"
        cot_do = "B"
        kq_tu_cot = "C"
        socot_kq = 2
        kq_den_cot = 12
    Case "MATERIAL_SHORTAGE":
        cot_historys = "A"
        cot_do = "B"
        kq_tu_cot = "N"
        socot_kq = 1
        kq_den_cot = 5
    Case "MATER_ITEM":
        cot_historys = "L"
        cot_do = "A"
        kq_tu_cot = "E"
        socot_kq = 3
        kq_den_cot = 14
End Select

Tức bạn phải nhập cot_historys, cot_do, kq_tu_cot, socot_kq, kq_den_cot cho từng sheet. Khi thêm sheet mới thì thêm cot_historys, cot_do, kq_tu_cot, socot_kq, kq_den_cot cho sheet mới.

Vd.
"thêm 1 sheet SPEED_MACHINE, điều kiện lấy là nếu tìm thấy cột L của historys bên cột B sheet SPEED_MACHINE thì lấy các cột E F G H I trả về vùng AV, AW, AX, AY, AZ sheet HISTORYS, nếu không tìm thấy thì không làm gì cả."

thì
cot_historys = "L" <- lấy giá trị ở cột "L" của HISTORYS hoặc SUMMARY để tìm kiếm
cot_do = "B" <- dò tìm ở cột "B" của sheet thêm là SPEED_MACHINE
kq_tu_cot = "E" <- cột đầu tiên lấy kết quả từ SPEED_MACHINE là cột "E"
socot_kq = 5 <- tính từ cột "E" lấy tổng cộng 5 cột
kq_den_cot = 23 <- mảng Z_AQ sẽ được nhập xuống HISTORYS hoặc SUMMARY vào các cột của Z:AQ. Cột AV sẽ tương ứng với cột 23 trong mảng Z_AQ. Vì thế kq_den_cot = 23.

Tóm lại nếu bạn dùng phiên bản dài dòng hơn như ở trên thì phải thêm 1 CASE
Case "SPEED_MACHINE":
cot_historys = "L"
cot_do = "B"
kq_tu_cot = "E"
socot_kq = 5
kq_den_cot = 23


3. Trong module ThisWorkbook có code trong Sub Workbook_SheetChange. Mỗi khi có sự thay đổi trong sheet nào đó của tập tin mà không phải là HISTORYS và SUMMARY thì code trong Workbook_SheetChange sẽ NGAY LẬP TỨC gọi sub duyet_KHAC, nhưng code trong sub duyet_KHAC chỉ được thực hiện khi tên sheet được liệt kê trong Select ... Case ... End Select. Hiện tại danh sách mới chỉ có: "SHIPOUT", "ORDER_SCAN", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL", "MATERIAL_SHORTAGE", "BCNK", "MATER_ITEM".

4. Trong module SUMMARY có sub Worksheet_Change. Khi có bất cứ sự thay đổi nào trong SUMMARY, từ cột E tới cột AS, thì code sẽ tính giá trị cho cột BA. Nếu có sự thay đổi trong A:AU thì tính giá trị cho cột BB.

5. Bạn tự test thật kỹ vì con người ai cũng có thể nhầm lẫn. Việc của bạn, chỉ bạn hiểu rõ dữ liệu, nên cách test bạn phải biết, không ai giúp được phần test. Tôi ghi chú rất nhiều. Cần đọc kỹ để hiểu ý nghĩa các biến, những việc mà từng dòng code thực hiện.

Hình như bạn có nói là các sheet như SHIPOUT có ít dòng mà sao tôi thấy thực tế khác xa.
SHIPOUT = 18331 dòng
ORDER_SCAN = 17455 dòng
BY_DATE = 32978 dòng
KITTING = 31209 dòng
 

File đính kèm

Upvote 0
Code được viết với giả thiết sau đây:
1. Khi nhấn RefreshAll thì thực hiện code sub RefreshAll

a. Duyệt FRU để cập nhật HISTORYS và SUMMARY. Sub RefreshAll sẽ gọi sub duyet_FRU 2 lần để cập nhật HISTORYS và SUMMARY.
- kiểm tra từng dòng (A & B & ... & AB) của FRU có xuất hiện trong HISTORYS hoặc SUMMARY hay không. Nếu đã có thì làm mới B:E, S, K, Y và Z. Nếu chưa có thì thêm dòng đó vào cuối HISTORYS hoặc SUMMARY

- nếu dòng (A & B & ... & AB) nào đó của SUMMARY không có trong FRU thì xóa khỏi SUMMARY

b. Sub RefreshAll cũng gọi sub duyet_KHAC nhiều lần, mỗi lần để duyệt từng sheet SHIPOUT, MATER_ITEM, ... để cập nhật HISTORYS và SUMMARY

2. Trong sub duyet_KHAC do muốn rút gọn code nên tôi có đoạn
Mã:
'    cot_historys
    Select Case sheet_can_duyet_name
        Case "SHIPOUT", "ORDER_SCAN", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL", "MATERIAL_SHORTAGE", "BCNK": cot_historys = "A"
        Case "MATER_ITEM": cot_historys = "L"
    End Select
'    cot_do
    Select Case sheet_can_duyet_name
        Case "SHIPOUT", "ORDER_SCAN", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL", "MATER_ITEM": cot_do = "A"
        Case "MATERIAL_SHORTAGE", "BCNK": cot_do = "B"
    End Select
'    kq_tu_cot
    Select Case sheet_can_duyet_name
        Case "SHIPOUT", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL": kq_tu_cot = "B"
        Case "ORDER_SCAN", "BCNK": kq_tu_cot = "C"
        Case "MATERIAL_SHORTAGE": kq_tu_cot = "N"
        Case "MATER_ITEM": kq_tu_cot = "E"
    End Select
'    socot_kq
    Select Case sheet_can_duyet_name
        Case "SHIPOUT", "BCNK": socot_kq = 2
        Case "ORDER_SCAN", "BY_DATE", "KITTING", "MATERIAL_SHORTAGE", "SOL_CANCEL": socot_kq = 1
        Case "PRINT_STAGE", "CUT_STAGE", "MATER_ITEM": socot_kq = 3
    End Select
'    kq_den_cot
    Select Case sheet_can_duyet_name
        Case "SHIPOUT": kq_den_cot = 1
        Case "ORDER_SCAN": kq_den_cot = 3
        Case "BY_DATE": kq_den_cot = 17
        Case "KITTING": kq_den_cot = 4
        Case "MATERIAL_SHORTAGE": kq_den_cot = 5
        Case "PRINT_STAGE": kq_den_cot = 6
        Case "CUT_STAGE": kq_den_cot = 9
        Case "BCNK": kq_den_cot = 12
        Case "SOL_CANCEL": kq_den_cot = 18
        Case "MATER_ITEM": kq_den_cot = 14
    End Select

Nếu bạn cảm thấy khó hiểu thì thay toàn bộ đoạn trên bằng
Mã:
Select Case sheet_can_duyet_name
    Case "SHIPOUT":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 2
        kq_den_cot = 1
    Case "BY_DATE":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 1
        kq_den_cot = 17
    Case "KITTING":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 1
        kq_den_cot = 4
    Case "PRINT_STAGE":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 3
        kq_den_cot = 6
    Case "CUT_STAGE":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 3
        kq_den_cot = 9
    Case "SOL_CANCEL":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 1
        kq_den_cot = 18
    Case "ORDER_SCAN":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "C"
        socot_kq = 1
        kq_den_cot = 3
    Case "BCNK":
        cot_historys = "A"
        cot_do = "B"
        kq_tu_cot = "C"
        socot_kq = 2
        kq_den_cot = 12
    Case "MATERIAL_SHORTAGE":
        cot_historys = "A"
        cot_do = "B"
        kq_tu_cot = "N"
        socot_kq = 1
        kq_den_cot = 5
    Case "MATER_ITEM":
        cot_historys = "L"
        cot_do = "A"
        kq_tu_cot = "E"
        socot_kq = 3
        kq_den_cot = 14
End Select

Tức bạn phải nhập cot_historys, cot_do, kq_tu_cot, socot_kq, kq_den_cot cho từng sheet. Khi thêm sheet mới thì thêm cot_historys, cot_do, kq_tu_cot, socot_kq, kq_den_cot cho sheet mới.

Vd.
"thêm 1 sheet SPEED_MACHINE, điều kiện lấy là nếu tìm thấy cột L của historys bên cột B sheet SPEED_MACHINE thì lấy các cột E F G H I trả về vùng AV, AW, AX, AY, AZ sheet HISTORYS, nếu không tìm thấy thì không làm gì cả."

thì
cot_historys = "L" <- lấy giá trị ở cột "L" của HISTORYS hoặc SUMMARY để tìm kiếm
cot_do = "B" <- dò tìm ở cột "B" của sheet thêm là SPEED_MACHINE
kq_tu_cot = "E" <- cột đầu tiên lấy kết quả từ SPEED_MACHINE là cột "E"
socot_kq = 5 <- tính từ cột "E" lấy tổng cộng 5 cột
kq_den_cot = 23 <- mảng Z_AQ sẽ được nhập xuống HISTORYS hoặc SUMMARY vào các cột của Z:AQ. Cột AV sẽ tương ứng với cột 23 trong mảng Z_AQ. Vì thế kq_den_cot = 23.

Tóm lại nếu bạn dùng phiên bản dài dòng hơn như ở trên thì phải thêm 1 CASE
Case "SPEED_MACHINE":
cot_historys = "L"
cot_do = "B"
kq_tu_cot = "E"
socot_kq = 5
kq_den_cot = 23


3. Trong module ThisWorkbook có code trong Sub Workbook_SheetChange. Mỗi khi có sự thay đổi trong sheet nào đó của tập tin mà không phải là HISTORYS và SUMMARY thì code trong Workbook_SheetChange sẽ NGAY LẬP TỨC gọi sub duyet_KHAC, nhưng code trong sub duyet_KHAC chỉ được thực hiện khi tên sheet được liệt kê trong Select ... Case ... End Select. Hiện tại danh sách mới chỉ có: "SHIPOUT", "ORDER_SCAN", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL", "MATERIAL_SHORTAGE", "BCNK", "MATER_ITEM".

4. Trong module SUMMARY có sub Worksheet_Change. Khi có bất cứ sự thay đổi nào trong SUMMARY, từ cột E tới cột AS, thì code sẽ tính giá trị cho cột BA. Nếu có sự thay đổi trong A:AU thì tính giá trị cho cột BB.

5. Bạn tự test thật kỹ vì con người ai cũng có thể nhầm lẫn. Việc của bạn, chỉ bạn hiểu rõ dữ liệu, nên cách test bạn phải biết, không ai giúp được phần test. Tôi ghi chú rất nhiều. Cần đọc kỹ để hiểu ý nghĩa các biến, những việc mà từng dòng code thực hiện.

Hình như bạn có nói là các sheet như SHIPOUT có ít dòng mà sao tôi thấy thực tế khác xa.
SHIPOUT = 18331 dòng
ORDER_SCAN = 17455 dòng
BY_DATE = 32978 dòng
KITTING = 31209 dòng
A batman1 ơi em đang xem lại bài của a huonghckt và bài a vừa hướng dẫn nhưng em vẫn chưa hiểu hết được, em đang mò mẫm từng chút một nhưng thật sự em đang mong chờ a viết lại theo bài 36 37 vừa được a tóm tắt sau đó em sẽ đọc lại tiếp bài 39, hiện tại em không có khả năng code được sẽ mất rất nhiều thời gian để em tự học nữa ạ, em rất mong a giúp em
 
Upvote 0
A batman1 ơi em đang xem lại bài của a huonghckt và bài a vừa hướng dẫn nhưng em vẫn chưa hiểu hết được, em đang mò mẫm từng chút một nhưng thật sự em đang mong chờ a viết lại theo bài 36 37 vừa được a tóm tắt sau đó em sẽ đọc lại tiếp bài 39, hiện tại em không có khả năng code được sẽ mất rất nhiều thời gian để em tự học nữa ạ, em rất mong a giúp em
Code bài 39 được viết cho một giả thiết nhất định. Nếu bạn đọc giả thiết mà tôi viết trong bài 39 thì bạn sẽ thấy đúng như đã thống nhất ở bài 36, 37.
Tôi phải viết code mới vì code cũ kiểm tra dữ liệu mới hay cũ chỉ trên cơ sở cột A (SOL). Bạn lại muốn trên cơ sở cả dòng - A & B & ... & AB. Hoặc là trên sở chỉ cột A hoặc trên cơ sở CẢ DÒNG A & B & ... & AB. Không phải vô cớ tôi mất rất nhiều thời gian để thống nhất với bạn để bây giờ bạn lại thay đổi ý định.
Trong bài 37 bạn có thêm ý cho rõ thì code trong ThisWorkbook (điểm 3 trong bài 39) chính là thực hiện việc đó.

Tôi có thể giúp bạn viết code, và tôi chỉ quan tâm, liệu code có sai sót gì không. Tôi không quan tâm bạn có hiểu không. Không ai có nhiệm vụ đào tạo bạn. Nếu kiến thức của bạn không đủ để hiểu code thì chả ai giúp được bạn. Tôi đã cố gắng hết sức bằng cách chú thích, giải thích hầu như mỗi dòng code.
 
Upvote 0
Code bài 39 được viết cho một giả thiết nhất định. Nếu bạn đọc giả thiết mà tôi viết trong bài 39 thì bạn sẽ thấy đúng như đã thống nhất ở bài 36, 37.
Tôi phải viết code mới vì code cũ kiểm tra dữ liệu mới hay cũ chỉ trên cơ sở cột A (SOL). Bạn lại muốn trên cơ sở cả dòng - A & B & ... & AB. Hoặc là trên sở chỉ cột A hoặc trên cơ sở CẢ DÒNG A & B & ... & AB. Không phải vô cớ tôi mất rất nhiều thời gian để thống nhất với bạn để bây giờ bạn lại thay đổi ý định.
Trong bài 37 bạn có thêm ý cho rõ thì code trong ThisWorkbook (điểm 3 trong bài 39) chính là thực hiện việc đó.

Tôi có thể giúp bạn viết code, và tôi chỉ quan tâm, liệu code có sai sót gì không. Tôi không quan tâm bạn có hiểu không. Không ai có nhiệm vụ đào tạo bạn. Nếu kiến thức của bạn không đủ để hiểu code thì chả ai giúp được bạn. Tôi đã cố gắng hết sức bằng cách chú thích, giải thích hầu như mỗi dòng code.
Dạ đúng ạ a ghi chú chi tiết là quá hoàn hảo rồi, còn lại em sẽ tự phải tìm hiểu
 
Upvote 0
Code được viết với giả thiết sau đây:
1. Khi nhấn RefreshAll thì thực hiện code sub RefreshAll

a. Duyệt FRU để cập nhật HISTORYS và SUMMARY. Sub RefreshAll sẽ gọi sub duyet_FRU 2 lần để cập nhật HISTORYS và SUMMARY.
- kiểm tra từng dòng (A & B & ... & AB) của FRU có xuất hiện trong HISTORYS hoặc SUMMARY hay không. Nếu đã có thì làm mới B:E, S, K, Y và Z. Nếu chưa có thì thêm dòng đó vào cuối HISTORYS hoặc SUMMARY

- nếu dòng (A & B & ... & AB) nào đó của SUMMARY không có trong FRU thì xóa khỏi SUMMARY

b. Sub RefreshAll cũng gọi sub duyet_KHAC nhiều lần, mỗi lần để duyệt từng sheet SHIPOUT, MATER_ITEM, ... để cập nhật HISTORYS và SUMMARY

2. Trong sub duyet_KHAC do muốn rút gọn code nên tôi có đoạn
Mã:
'    cot_historys
    Select Case sheet_can_duyet_name
        Case "SHIPOUT", "ORDER_SCAN", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL", "MATERIAL_SHORTAGE", "BCNK": cot_historys = "A"
        Case "MATER_ITEM": cot_historys = "L"
    End Select
'    cot_do
    Select Case sheet_can_duyet_name
        Case "SHIPOUT", "ORDER_SCAN", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL", "MATER_ITEM": cot_do = "A"
        Case "MATERIAL_SHORTAGE", "BCNK": cot_do = "B"
    End Select
'    kq_tu_cot
    Select Case sheet_can_duyet_name
        Case "SHIPOUT", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL": kq_tu_cot = "B"
        Case "ORDER_SCAN", "BCNK": kq_tu_cot = "C"
        Case "MATERIAL_SHORTAGE": kq_tu_cot = "N"
        Case "MATER_ITEM": kq_tu_cot = "E"
    End Select
'    socot_kq
    Select Case sheet_can_duyet_name
        Case "SHIPOUT", "BCNK": socot_kq = 2
        Case "ORDER_SCAN", "BY_DATE", "KITTING", "MATERIAL_SHORTAGE", "SOL_CANCEL": socot_kq = 1
        Case "PRINT_STAGE", "CUT_STAGE", "MATER_ITEM": socot_kq = 3
    End Select
'    kq_den_cot
    Select Case sheet_can_duyet_name
        Case "SHIPOUT": kq_den_cot = 1
        Case "ORDER_SCAN": kq_den_cot = 3
        Case "BY_DATE": kq_den_cot = 17
        Case "KITTING": kq_den_cot = 4
        Case "MATERIAL_SHORTAGE": kq_den_cot = 5
        Case "PRINT_STAGE": kq_den_cot = 6
        Case "CUT_STAGE": kq_den_cot = 9
        Case "BCNK": kq_den_cot = 12
        Case "SOL_CANCEL": kq_den_cot = 18
        Case "MATER_ITEM": kq_den_cot = 14
    End Select

Nếu bạn cảm thấy khó hiểu thì thay toàn bộ đoạn trên bằng
Mã:
Select Case sheet_can_duyet_name
    Case "SHIPOUT":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 2
        kq_den_cot = 1
    Case "BY_DATE":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 1
        kq_den_cot = 17
    Case "KITTING":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 1
        kq_den_cot = 4
    Case "PRINT_STAGE":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 3
        kq_den_cot = 6
    Case "CUT_STAGE":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 3
        kq_den_cot = 9
    Case "SOL_CANCEL":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "B"
        socot_kq = 1
        kq_den_cot = 18
    Case "ORDER_SCAN":
        cot_historys = "A"
        cot_do = "A"
        kq_tu_cot = "C"
        socot_kq = 1
        kq_den_cot = 3
    Case "BCNK":
        cot_historys = "A"
        cot_do = "B"
        kq_tu_cot = "C"
        socot_kq = 2
        kq_den_cot = 12
    Case "MATERIAL_SHORTAGE":
        cot_historys = "A"
        cot_do = "B"
        kq_tu_cot = "N"
        socot_kq = 1
        kq_den_cot = 5
    Case "MATER_ITEM":
        cot_historys = "L"
        cot_do = "A"
        kq_tu_cot = "E"
        socot_kq = 3
        kq_den_cot = 14
End Select

Tức bạn phải nhập cot_historys, cot_do, kq_tu_cot, socot_kq, kq_den_cot cho từng sheet. Khi thêm sheet mới thì thêm cot_historys, cot_do, kq_tu_cot, socot_kq, kq_den_cot cho sheet mới.

Vd.
"thêm 1 sheet SPEED_MACHINE, điều kiện lấy là nếu tìm thấy cột L của historys bên cột B sheet SPEED_MACHINE thì lấy các cột E F G H I trả về vùng AV, AW, AX, AY, AZ sheet HISTORYS, nếu không tìm thấy thì không làm gì cả."

thì
cot_historys = "L" <- lấy giá trị ở cột "L" của HISTORYS hoặc SUMMARY để tìm kiếm
cot_do = "B" <- dò tìm ở cột "B" của sheet thêm là SPEED_MACHINE
kq_tu_cot = "E" <- cột đầu tiên lấy kết quả từ SPEED_MACHINE là cột "E"
socot_kq = 5 <- tính từ cột "E" lấy tổng cộng 5 cột
kq_den_cot = 23 <- mảng Z_AQ sẽ được nhập xuống HISTORYS hoặc SUMMARY vào các cột của Z:AQ. Cột AV sẽ tương ứng với cột 23 trong mảng Z_AQ. Vì thế kq_den_cot = 23.

Tóm lại nếu bạn dùng phiên bản dài dòng hơn như ở trên thì phải thêm 1 CASE
Case "SPEED_MACHINE":
cot_historys = "L"
cot_do = "B"
kq_tu_cot = "E"
socot_kq = 5
kq_den_cot = 23


3. Trong module ThisWorkbook có code trong Sub Workbook_SheetChange. Mỗi khi có sự thay đổi trong sheet nào đó của tập tin mà không phải là HISTORYS và SUMMARY thì code trong Workbook_SheetChange sẽ NGAY LẬP TỨC gọi sub duyet_KHAC, nhưng code trong sub duyet_KHAC chỉ được thực hiện khi tên sheet được liệt kê trong Select ... Case ... End Select. Hiện tại danh sách mới chỉ có: "SHIPOUT", "ORDER_SCAN", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL", "MATERIAL_SHORTAGE", "BCNK", "MATER_ITEM".

4. Trong module SUMMARY có sub Worksheet_Change. Khi có bất cứ sự thay đổi nào trong SUMMARY, từ cột E tới cột AS, thì code sẽ tính giá trị cho cột BA. Nếu có sự thay đổi trong A:AU thì tính giá trị cho cột BB.

5. Bạn tự test thật kỹ vì con người ai cũng có thể nhầm lẫn. Việc của bạn, chỉ bạn hiểu rõ dữ liệu, nên cách test bạn phải biết, không ai giúp được phần test. Tôi ghi chú rất nhiều. Cần đọc kỹ để hiểu ý nghĩa các biến, những việc mà từng dòng code thực hiện.

Hình như bạn có nói là các sheet như SHIPOUT có ít dòng mà sao tôi thấy thực tế khác xa.
SHIPOUT = 18331 dòng
ORDER_SCAN = 17455 dòng
BY_DATE = 32978 dòng
KITTING = 31209 dòng
A batman1 ơi em có chút hơi khó hiểu về file đính kem a gửi vì nó giống file a huonghctk em xem mãi rồi vì em copy code của a vào lắp ghép thì ko thế chạy a xem lại giúp em với
 
Upvote 0
A batman1 ơi em có chút hơi khó hiểu về file đính kem a gửi vì nó giống file a huonghctk em xem mãi rồi vì em copy code của a vào lắp ghép thì ko thế chạy a xem lại giúp em với
Tôi không hiểu bạn nói gì.

À mà nếu tập tin tôi đính kèm giống y như tập tin của bạn HUONGHCKT thì cứ coi như không có tập tin của tôi đi. Bạn cứ nghiên cứu tập tin của bạn HUONGHCKT là được rồi.
 
Upvote 0
Tôi không hiểu bạn nói gì.

À mà nếu tập tin tôi đính kèm giống y như tập tin của bạn HUONGHCKT thì cứ coi như không có tập tin của tôi đi. Bạn cứ nghiên cứu tập tin của bạn HUONGHCKT là được rồi.
Em xem rồi nhưng giờ em không biết ghép code như thế nào ấy thực tế em đang nghĩ a viết theo file em gửi ở bài 32 được tóm tắt xuống bài 36 bà 37 vì còn nhiều phần mở rộng như cột BC cập nhật ngày thay đổi, hiện tại thì em đang ngồi ghép nhưng khả năng có hạn ghép không nổi, vì code trong file a gửi là code khác bên ngoài bài viết, em không dám đòi hỏi nhiều, em cám ơn a đã giúp ạ
 
Lần chỉnh sửa cuối:
Upvote 0
Em xem rồi nhưng giờ em không biết ghép code như thế nào ấy thực tế em đang nghĩ a viết theo file em gửi ở bài 32 được tóm tắt xuống bài 36 bà 37 vì còn nhiều phần mở rộng như cột BC cập nhật ngày thay đổi, hiện tại thì em đang ngồi ghép nhưng khả năng có hạn ghép không nổi, vì code trong file a gửi là code khác bên ngoài bài viết, em không dám đòi hỏi nhiều, em cám ơn a đã giúp ạ
Code tôi đã viết, việc của bạn chỉ là test thôi. Tập tin đính kèm ở bài 39 đã làm hết mọi việc mà tôi đã thống nhất với bạn. Có code cho RefreshAll, có code để duyệt mỗi tập tin SHIPOUT, MATER_ITEM, ... khi chúng thay đổi, có cập nhật ngày thay đổi trong cột BC, có code để tính giá trị cho SUMMARY!BA, BB thay cho công thức.

Trong bài 39 có tập tin. Bạn đã test chưa mà bạn viết những điêu vô lý như trên? Nếu test rồi mà chỗ nào sai hoặc chưa đúng ý thì phải cho ví dụ cụ thể. Tôi không tranh luận khi bạn chỉ nói chung chung vài câu. Code có hết trong tập tin ở bài 39 rồi, bạn còn muốn code nào nữa? Code có rồi thì nhiệm vụ của bạn là test và cho góp ý. Chứ viết code nào nữa? Ghép code nào nữa?

Muốn test RefreshAll? Thì nhấn nút RefreshAll ở sheet HISTORYS rồi kiểm tra thôi. Muốn test xem có code nào chạy khi vd. SHIPOUT thay đổi? Thì thử thay đổi bằng tay dữ liệu trong sheet SHIPOUT thôi. Muốn xem có ngày trong BC? Thì nhập bằng tay dòng mới trong FRU mà có S = "AWAIT..." rồi nhấn RefreshAll để kiểm tra thôi. Muốn kiểm tra giá trị trong BA, BB của SUMMARY? Thì thử thay đổi bằng tay dòng nào đó trong SUMMARY thôi. Tôi phải dạy bạn cách test à?
 
Upvote 0
Code tôi đã viết, việc của bạn chỉ là test thôi. Tập tin đính kèm ở bài 39 đã làm hết mọi việc mà tôi đã thống nhất với bạn. Có code cho RefreshAll, có code để duyệt mỗi tập tin SHIPOUT, MATER_ITEM, ... khi chúng thay đổi, có cập nhật ngày thay đổi trong cột BC, có code để tính giá trị cho SUMMARY!BA, BB thay cho công thức.

Trong bài 39 có tập tin. Bạn đã test chưa mà bạn viết những điêu vô lý như trên? Nếu test rồi mà chỗ nào sai hoặc chưa đúng ý thì phải cho ví dụ cụ thể. Tôi không tranh luận khi bạn chỉ nói chung chung vài câu. Code có hết trong tập tin ở bài 39 rồi, bạn còn muốn code nào nữa? Code có rồi thì nhiệm vụ của bạn là test và cho góp ý. Chứ viết code nào nữa? Ghép code nào nữa?

Muốn test RefreshAll? Thì nhấn nút RefreshAll ở sheet HISTORYS rồi kiểm tra thôi. Muốn test xem có code nào chạy khi vd. SHIPOUT thay đổi? Thì thử thay đổi bằng tay dữ liệu trong sheet SHIPOUT thôi. Muốn xem có ngày trong BC? Thì nhập bằng tay dòng mới trong FRU mà có S = "AWAIT..." rồi nhấn RefreshAll để kiểm tra thôi. Muốn kiểm tra giá trị trong BA, BB của SUMMARY? Thì thử thay đổi bằng tay dòng nào đó trong SUMMARY thôi. Tôi phải dạy bạn cách test à?
Dạ, em hiểu là em phải test, nhưng ý em là trong file a gửi em không thấy có đoạn code nào như a hướng dẫn, vì vậy khi em muốn thêm đoạn code của a vào thì em không biết thêm vào đâu để chạy, em không có ý tranh luận đâu ạ, em không dám tranh luận mà em chưa hiểu em muốn a chỉ giúp em thôi.
 
Upvote 0
.
File bài #39 bị lộn tiệm. Ở bài #43 người ta nói vậy cũng nên quay về bài #39 tải lại file đó và kiểm tra.

Đăng nhầm file là chuyện bình thường.
 
Upvote 0
Dạ, em hiểu là em phải test, nhưng ý em là trong file a gửi em không thấy có đoạn code nào như a hướng dẫn, vì vậy khi em muốn thêm đoạn code của a vào thì em không biết thêm vào đâu để chạy, em không có ý tranh luận đâu ạ, em không dám tranh luận mà em chưa hiểu em muốn a chỉ giúp em thôi.
Chết thật, tôi cứ đinh ninh là đã đính kèm đúng tập tin.

Nếu bạn viết rõ là bạn không tìm thấy sub RefreshAll, sub duyet_FRU, sub duyet_KHAC trong tập tin thì có thể tôi sẽ giật mình và kiểm tra lại. Còn chung chung thế thì mấy phút trước khi đọc
ý em là trong file a gửi em không thấy có đoạn code nào như a hướng dẫn
tôi mới giật mình và kiểm tra lại. Đó không phải là tập tin với code của tôi mà là code của bạn. Khi tôi viết xong bài này (tôi luôn viết trong notepad, khi xong mới copy -> paste lên GPE) thì mới nhìn thấy bài 48

Bạn hãy tải lại tập tin. Toàn bộ code trong Module1, module SUMMARY và module ThisWorkbook.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Chết thật, tôi cứ đinh ninh là đã đính kèm đúng tập tin.

Nếu bạn viết rõ là bạn không tìm thấy sub RefreshAll, sub duyet_FRU, sub duyet_KHAC trong tập tin thì có thể tôi sẽ giật mình và kiểm tra lại. Còn chung chung thế thì mấy phút trước khi đọc

tôi mới giật mình và kiểm tra lại. Đó không phải là tập tin với code của tôi mà là code của bạn. Khi tôi viết xong bài này (tôi luôn viết trong notepad, khi xong mới copy -> paste lên GPE) thì mới nhìn thấy bài 48

Bạn hãy tải lại tập tin. Toàn bộ code trong Module1, module SUMMARY và module ThisWorkbook.
Em cám ơn anh nhé, em đã chạy thử, về phần thêm các sheet thì em dựa vào phần a ghi chú em có thể thêm được rồi
nhưng sheet historys mỗi khi nhấn refresh sẽ lấy tất cả nhưng số dòng hiện có của FRU và thêm nối tiếp vào sheet historys sẽ dẫn đến trùng lặp, chứ không lấy được dữ liệu mới nữa, số dòng trắng sinh ra ở sheet summary cũng tăng tối đa hơn 1 triệu dòng em thử kéo thanh trượt xuống thấy vậy, chỉ cần nhấn nút refresh vài lần sẽ dẫn đến lỗi "notResponding" không phản hồi. A xem giúp em với ạ.
 

File đính kèm

Upvote 0
Em cám ơn anh nhé, em đã chạy thử, về phần thêm các sheet thì em dựa vào phần a ghi chú em có thể thêm được rồi
nhưng sheet historys mỗi khi nhấn refresh sẽ lấy tất cả nhưng số dòng hiện có của FRU và thêm nối tiếp vào sheet historys sẽ dẫn đến trùng lặp, chứ không lấy được dữ liệu mới nữa, số dòng trắng sinh ra ở sheet summary cũng tăng tối đa hơn 1 triệu dòng em thử kéo thanh trượt xuống thấy vậy, chỉ cần nhấn nút refresh vài lần sẽ dẫn đến lỗi "notResponding" không phản hồi. A xem giúp em với ạ.
Muốn test thì trước hết phải có dữ liệu chuẩn.

Bạn thêm một sheet mới và nhập vào A1 công thức
Mã:
=FRU!C2=HISTORYS!C2

Kết quả có FALSE. Nhìn bằng mắt có vẻ là cùng là "Ngày 06 tháng 10 năm 2021". Nhưng thực ra chỉ có HISTORYS!C2 là ngày tháng chuẩn, còn FRU!C2 là ngày tháng nhái ở dạng Text. Vì thế Excel cho là chúng không bằng nhau. Hậu quả ra sao? Lấy ví dụ:

FRU
A2 = 57038842-1, B2 = HNK, C2 = <23.07.2021 ở dạng text>

HISTORYS
A2 = 57038842-1, B2 = HNK, C2 = <23.07.2021 ở dạng Ngày tháng chuẩn>

Do bạn muốn ghép các cột nên từ FRU có dòng 1 = 57038842-1#HNK#<23.07.2021 ở dạng text>..., trong HISTORYS có 57038842-1#HNK#<23.07.2021 ở dạng Ngày tháng chuẩn> ... Rõ ràng 2 chuỗi không như nhau và dòng 1 được coi như dòng mới.

Thử có tất cả các ngày tháng đều chuẩn rồi mới chạy code thì rõ thôi. Trong FRU chỉ có I, J, K chứa ngày tháng chuẩn còn C, D, E, AA, AB, AE, AF, AG chứa ngày tháng nhái.

Tôi thú thực với bạn không một chút ngượng ngùng là tôi không có kinh nghiệm xoay xở với những dữ liệu ngày tháng nhái. Tôi đã nói về vấn đề này từ bài 7 trở đi. Bạn nên viết rõ và nhờ mọi người, chịu khó chờ ai đó có kinh nghiệm làm việc với ngày tháng không chuẩn. Trên GPE những người như thế cứ đi vài bước lại gặp.

Mà theo tôi khi test ở bước đầu để kiểm tra xem code có lỗi không, có đúng ý không, thì nên soạn dữ liệu đầu vào ít thôi - vài ba dòng. Lúc đó dễ theo dõi, dễ kiểm tra hơn nhiều.
 
Upvote 0
Muốn test thì trước hết phải có dữ liệu chuẩn.

Bạn thêm một sheet mới và nhập vào A1 công thức
Mã:
=FRU!C2=HISTORYS!C2

Kết quả có FALSE. Nhìn bằng mắt có vẻ là cùng là "Ngày 06 tháng 10 năm 2021". Nhưng thực ra chỉ có HISTORYS!C2 là ngày tháng chuẩn, còn FRU!C2 là ngày tháng nhái ở dạng Text. Vì thế Excel cho là chúng không bằng nhau. Hậu quả ra sao? Lấy ví dụ:

FRU
A2 = 57038842-1, B2 = HNK, C2 = <23.07.2021 ở dạng text>

HISTORYS
A2 = 57038842-1, B2 = HNK, C2 = <23.07.2021 ở dạng Ngày tháng chuẩn>

Do bạn muốn ghép các cột nên từ FRU có dòng 1 = 57038842-1#HNK#<23.07.2021 ở dạng text>..., trong HISTORYS có 57038842-1#HNK#<23.07.2021 ở dạng Ngày tháng chuẩn> ... Rõ ràng 2 chuỗi không như nhau và dòng 1 được coi như dòng mới.

Thử có tất cả các ngày tháng đều chuẩn rồi mới chạy code thì rõ thôi. Trong FRU chỉ có I, J, K chứa ngày tháng chuẩn còn C, D, E, AA, AB, AE, AF, AG chứa ngày tháng nhái.

Tôi thú thực với bạn không một chút ngượng ngùng là tôi không có kinh nghiệm xoay xở với những dữ liệu ngày tháng nhái. Tôi đã nói về vấn đề này từ bài 7 trở đi. Bạn nên viết rõ và nhờ mọi người, chịu khó chờ ai đó có kinh nghiệm làm việc với ngày tháng không chuẩn. Trên GPE những người như thế cứ đi vài bước lại gặp.

Mà theo tôi khi test ở bước đầu để kiểm tra xem code có lỗi không, có đúng ý không, thì nên soạn dữ liệu đầu vào ít thôi - vài ba dòng. Lúc đó dễ theo dõi, dễ kiểm tra hơn nhiều.
Dạ, em đã xóa bớt dữ liệu chỉ để lại một vài dòng để chạy thử, kết quả cho thấy sheet summary hoạt động ổn hơn chỉ còn lại số dòng trống sinh ra hơn 1 triệu dòng nó gây nặng quá.
Đối với phần sheet historys
đến lúc a nói đến câu này
Do bạn muốn ghép các cột nên từ FRU có dòng 1 = 57038842-1#HNK#<23.07.2021 ở dạng text>..., trong HISTORYS có 57038842-1#HNK#<23.07.2021 ở dạng Ngày tháng chuẩn> ... Rõ ràng 2 chuỗi không như nhau và dòng 1 được coi như dòng mới. -> em mới hiểu hết được a sẽ ghép toàn bộ cột từ A đến AB thành một chuỗi giống như căn cước công dân không trùng nhau để đưa sang nối tiếp vào historys, và do khác nhau là phần ngày tháng không chuẩn
cái này mặc dù em đã chuyển bằng công thức để lấy ngày chuẩn nhưng mỗi lần ấn refresh all vẫn tiếp tục lấy vào một chuỗi khác trùng lặp với chuỗi ký tự đang có.

như vậy giờ a có thể lấy theo cách này được không ạ,
chỉ kiểm tra cột A sheet FRU với cột A sheet historys thôi, ví dụ nếu sheet FRU có 63283769-5 dòng A7 mà historys không có thì lấy 63283769-5 từ A7 sang nối tiếp vào historys đồng thời lấy tiếp từ B7 đến AB7 sang historys, vì cột A (SOL) là cột không bao giờ bị trùng lặp, thay vì a đang phải ghép A đến AB cũng rất vất vả.


giờ em mới hiểu hết được cấu trúc a vừa diễn tả, thực sự em cũng thấy nó phức tạp quá.
 

File đính kèm

Upvote 0
giờ em mới hiểu hết được cấu trúc a vừa diễn tả, thực sự em cũng thấy nó phức tạp quá.
Tôi đã mất rất nhiều bài để thống nhất với bạn chuyện so sánh A hay so sánh cả dòng A & B & ... & AB.

Tôi biết là với một dữ liệu "nào đó" thì cả hai cách là như nhau. Tức dữ liệu không tùy ý mà nó luôn ở "trạng thái" mà cả 2 cách so sánh A hay cả dòng là như nhau.

Chỉ có điều tôi không biết có luôn luôn đảm bảo cái "trạng thái" kia hay không. Rất nhiều người như bạn, không bao giờ mô tả dữ liệu đầu vào, nên những người như tôi không dám chắc chúng như thế nào. Chính vì thế tôi "bắt" bạn phải quyết định, tôi chỉ là người làm hộ. Nhiều người cứ làm như họ hiểu, đúng thực trạng hay không người nhờ ráng chịu. Tôi khác họ. Nếu tôi giúp thì tôi muốn người ta ý thức được những "nguy hiểm" tiềm năng. Để họ không bị bất ngờ khi gặp chúng.

Bây giờ lại chỉ so sánh cột A thì lại như "hồi đầu" tôi viết, đơn giản hơn. Lại phải tối nay tôi mới xem lại và chỉnh sửa.
 
Upvote 0
Chính vì thế tôi "bắt" bạn phải quyết định, tôi chỉ là người làm hộ. Nhiều người cứ làm như họ hiểu, đúng thực trạng hay không người nhờ ráng chịu. Tôi khác họ. Nếu tôi giúp thì tôi muốn người ta ý thức được những "nguy hiểm" tiềm năng
vâng em hiểu ạ, nếu không như vậy khiến cho cách xử lý khác dẫn đến kết quả khác nhau.
 
Upvote 0
vâng em hiểu ạ, nếu không như vậy khiến cho cách xử lý khác dẫn đến kết quả khác nhau.
Code được viết cho giả thiết ở bài 39, chỉ có 1 điểm khác biệt: khi duyệt FRU cho SUMMARY hoặc HISTORYS thì không tìm toàn bộ từng dòng của FRU trong SUMMARY hoặc HISTORYS mà chỉ tìm SOL từ cột A của FRU trong cột A của SUMMARY hoặc HISTORYS.

Khi có lỗi (error) thì phải: cung cấp tất cả các thao tác lần lượt để tôi tạo lại tình huống lỗi.

Khi có kết quả không mong muốn thì phải: cung cấp tất cả các thao tác lần lượt để tôi tạo lại tình huống sai. Cho biết kết quả chạy code sau hàng loạt thao tác ấy là gì, và cho biết theo yêu cầu thì kết quả phải là gì.

Tôi đã lược bỏ 1 triệu dòng thừa trong SUMMARY.
 

File đính kèm

Upvote 0
Code được viết cho giả thiết ở bài 39, chỉ có 1 điểm khác biệt: khi duyệt FRU cho SUMMARY hoặc HISTORYS thì không tìm toàn bộ từng dòng của FRU trong SUMMARY hoặc HISTORYS mà chỉ tìm SOL từ cột A của FRU trong cột A của SUMMARY hoặc HISTORYS.

Khi có lỗi (error) thì phải: cung cấp tất cả các thao tác lần lượt để tôi tạo lại tình huống lỗi.

Khi có kết quả không mong muốn thì phải: cung cấp tất cả các thao tác lần lượt để tôi tạo lại tình huống sai. Cho biết kết quả chạy code sau hàng loạt thao tác ấy là gì, và cho biết theo yêu cầu thì kết quả phải là gì.

Tôi đã lược bỏ 1 triệu dòng thừa trong SUMMARY.
Dạ, em cám ơn ạ, em sẽ chạy thử cẩn thận để xem có lỗi phát sinh không
 
Upvote 0
Code được viết cho giả thiết ở bài 39, chỉ có 1 điểm khác biệt: khi duyệt FRU cho SUMMARY hoặc HISTORYS thì không tìm toàn bộ từng dòng của FRU trong SUMMARY hoặc HISTORYS mà chỉ tìm SOL từ cột A của FRU trong cột A của SUMMARY hoặc HISTORYS.

Khi có lỗi (error) thì phải: cung cấp tất cả các thao tác lần lượt để tôi tạo lại tình huống lỗi.

Khi có kết quả không mong muốn thì phải: cung cấp tất cả các thao tác lần lượt để tôi tạo lại tình huống sai. Cho biết kết quả chạy code sau hàng loạt thao tác ấy là gì, và cho biết theo yêu cầu thì kết quả phải là gì.

Tôi đã lược bỏ 1 triệu dòng thừa trong SUMMARY.
A batman1 ơi sau một thời gian em chạy thử thì có vấn đề phát sinh.
Sub duyet_KHAC(ByVal sheet_can_duyet_name As String) ' khi sheet_can_duyet_name co thay doi thi cap nhat HISTORYS va SUMMARY
khi có thay đổi dữ liệu ở các sheet khác thì sẽ tự động cập nhật, cái này rất tiện lợi đối với sheet có vài trăm dòng thì chạy rất nhanh, nhưng khi có hàng nghìn dòng trở lên mỗi lần có 1 dòng thay đổi thì excel sẽ hiển thị "calculating" mất 10 đến 15 phút mới xong, sau đó vẫn phải nhấn nút "refresh all" thì dữ liệu mới cập nhật chuẩn được còn không nhấn nút một số trường hợp sẽ phát sinh #N/A bên sheet HISTORYS
vì vậy a có thể giúp em trong lúc các sheet có dữ liệu thay đổi thì không tự tính "calculating" tức là có thể nhập thoải mái cho đến khi nào nhập xong dữ liệu ở các sheet khác rồi nhấn nút refresh all thì dữ liệu mới được cập nhật.
cũng khá lâu em mới hỏi được anh vì lúc đó em cũng chưa biết nguyên nhân để diễn tả cho a hiểu.
 
Upvote 0
Sub duyet_KHAC(ByVal sheet_can_duyet_name As String) ' khi sheet_can_duyet_name co thay doi thi cap nhat HISTORYS va SUMMARY
khi có thay đổi dữ liệu ở các sheet khác thì sẽ tự động cập nhật, cái này rất tiện lợi đối với sheet có vài trăm dòng thì chạy rất nhanh, nhưng khi có hàng nghìn dòng trở lên mỗi lần có 1 dòng thay đổi thì excel sẽ hiển thị "calculating" mất 10 đến 15 phút mới xong, sau đó vẫn phải nhấn nút "refresh all" thì dữ liệu mới cập nhật chuẩn được
Bạn cần tập viết cụ thể, chính xác. Bạn nói về nút Refresh All. Nó nằm ở đâu vậy? Tôi xem qua thì trong sheet HISTORYS có nút "Refresh", không có "Refresh All". Trong OUTPUT có "Refresh All" nhưng nó không được gán cho sub nào. Hay là bạn muốn nói tới NÚT "Refresh" (không có All), được gán cho SUB Refresh All? NÚT Refresh All hay SUB Refresh All là 2 chuyện khác nhau hoàn toàn. Hãy tập nói, viết thật chính xác.

Ý bạn là khi chỉnh sửa các sheet nào thì không tự động chạy Sub duyet_KHAC? Bạn nên nhớ là tôi giúp bạn hơn 4 tháng trước và không ai có thể nhớ khi đó mình làm gì, vấn đề cụ thể ra sao, có những khúc mắc gì. Vì thế phải giải thích cụ thể. Bạn không muốn chạy Sub duyet_KHAC khi các sheet KHÁC đang có chỉnh sửa? Tức cụ thể là các sheet "ORDER_SCAN", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL", "MATERIAL_SHORTAGE", "BCNK" ...? Nếu thế thì:

1. Trong module ThisWorkbook xóa
Mã:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    If Sh.Name <> "HISTORYS" And Sh.Name <> "SUMMARY" Then duyet_KHAC Sh.Name
End Sub

2. Khi nào muốn làm mới thì nhấn NÚT Refresh trên sheet HISTORYS để chạy SUB Refresh All.
 
Upvote 0
Bạn cần tập viết cụ thể, chính xác. Bạn nói về nút Refresh All. Nó nằm ở đâu vậy? Tôi xem qua thì trong sheet HISTORYS có nút "Refresh", không có "Refresh All". Trong OUTPUT có "Refresh All" nhưng nó không được gán cho sub nào. Hay là bạn muốn nói tới NÚT "Refresh" (không có All), được gán cho SUB Refresh All? NÚT Refresh All hay SUB Refresh All là 2 chuyện khác nhau hoàn toàn. Hãy tập nói, viết thật chính xác.

Ý bạn là khi chỉnh sửa các sheet nào thì không tự động chạy Sub duyet_KHAC? Bạn nên nhớ là tôi giúp bạn hơn 4 tháng trước và không ai có thể nhớ khi đó mình làm gì, vấn đề cụ thể ra sao, có những khúc mắc gì. Vì thế phải giải thích cụ thể. Bạn không muốn chạy Sub duyet_KHAC khi các sheet KHÁC đang có chỉnh sửa? Tức cụ thể là các sheet "ORDER_SCAN", "BY_DATE", "KITTING", "PRINT_STAGE", "CUT_STAGE", "SOL_CANCEL", "MATERIAL_SHORTAGE", "BCNK" ...? Nếu thế thì:

1. Trong module ThisWorkbook xóa
Mã:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    If Sh.Name <> "HISTORYS" And Sh.Name <> "SUMMARY" Then duyet_KHAC Sh.Name
End Sub

2. Khi nào muốn làm mới thì nhấn NÚT Refresh trên sheet HISTORYS để chạy SUB Refresh All.
Dạ đúng rồi ạ, để em kiểm tra kỹ xem có lỗi gì nữa không
 
Upvote 0

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

Back
Top Bottom