Lọc dữ liệu theo điều kiện? (1 người xem)

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

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

pmhoang

Thành viên thường trực
Tham gia
4/7/08
Bài viết
269
Được thích
83
Mình mới học VBA, Minh lập trình File này để sử dụng, mà mấy hôm này cứ làm đi làm lại mà không được ở bước lọc dữ liệu (FilterData). Mình post file len GPE mong anh em giúp đở với. Thanhk GPE

Yêu Cầu Lọc Theo điều kiện
Xóa hết các hàng, chỉ để lại những hàng thỏa điều kiện bên dưới
Lấy VD là Beam B1
1. Ở đầu Loc lấy hàng dữ liệu có M3 giá trị nhỏ nhất (hàng 7 có M3= -6.607)
2. Ở giữa Loc lấy hàng dữ liệu có M3 giá trị lớn nhất (hàng 28 hoặc 29 cũng được có M3= 3.525)
3. Ở cuối Loc lấy hàng dữ liệu có M3 giá trĩ nhỏ nhất (hàng 53 có M3= -6.684)


File gởi kèm ở bên dưới, hoặc theo link sau:
http://www.megaupload.com/?d=4NVSWINB

Mình mới học VBA, Minh lập trình File này để sử dụng, mà mấy hôm này cứ làm đi làm lại mà không được ở bước lọc dữ liệu (FilterData). Mình post file len GPE mong anh em giúp đở với. Thanhk GPE

Yêu Cầu Lọc Theo điều kiện
Xóa hết các hàng, chỉ để lại những hàng thỏa điều kiện bên dưới
Lấy VD là Beam B1
Ở đầu Loc lấy hàng dữ liệu có M3 giá trị nhỏ nhất (hàng 7 có M3= -6.607)
Ở giữa Loc lấy hàng dữ liệu có M3 giá trị lớn nhất (hàng 28 hoặc 29 cũng được có M3= 3.525)
Ở cuối Loc lấy hàng dữ liệu có M3 giá trĩ nhỏ nhất (hàng 53 có M3= -6.684)
Lấy hàng có V2 nhỏ nhất (hàng 7 có V2= -5.94)
Lấy hàng có V2 lớn nhất (hàng 52 có V2= 6.09)


HTML:
Yêu Cầu Lọc Theo điều kiện
Xóa hết các hàng, chỉ để lại những hàng thỏa điều kiện bên dưới
Lấy VD là Beam B1
1. Ở Loc đầu, lấy hàng dữ liệu có M3 giá trị nhỏ nhất (hàng 7 có M3= -6.607)
2. Ở Loc giữa, lấy hàng dữ liệu có M3 giá trị lớn nhất (hàng 28 hoặc 29 cũng được có M3= 3.525)
3. Ở Loc cuối, lấy hàng dữ liệu có M3 giá trĩ nhỏ nhất (hàng 53 có M3= -6.684)
(chú ý: Loc ở đây không phải là lọc mà là 1 ký hiệu đại diện, nghĩa của nó là mặt cắt)

Mình có ghi chú bảng tính trong file như sau:
Cột Loc (Cột có tên Lốc là cột D) là vị trí mặt cắt của Beam, vị trí cắt này không phải lúc nào cũng tăng lên theo bội số 0.5, mà là 1 số nào đó
VD Loc (Loc ở đây được hiểu là mặt cắt) của B1 là: 0 0.5 1 1.5 2 … 6 (đầu Loc la 0 va cuối Loc là 6)
có nghĩa là đối với Beam B1 thì ta có các Loc (mặt cắt) đi từ đầu bên này đến đầu bên kia, Ví dụ như ta có B1 là cây thước gạch dài 6 (cm). (Loc di từ 0 đến 6)
0 , 0.5, 1 , 1.5, 2, 2.5, 3 , 3.5, 4, 4.5, 5, 5.5, 6 đó là các khoảng cách mà ta dùng dao chặt cây thước gạch ấy ra (mặt cắt)

Mỗi lần cắt (tương ứng vói 1 vết đứt - tương ướng với 1 hàng số liệu trên bảng tính) cho ra M3 tương ứng
Nếu cây thước gạch đó chia là 4 phần, 6/4=1.5 cm, thì phần 1/4 đầu tiên Loc (từ >= 0 đến <1.5) thì gọi là phần Loc đầu tiên
1/4 đoạn cuối (từ > 4.5 đến <=6) gọi là Loc cuối. Còn lại 2/4 ở giữa gọi là Loc giữa.
Cái đó là cái khó nhất vì đối với mỗi loại Beam ta phải phân đoạn cho nó để lấy số liệu.
Hi vong cac bạn sẽ hiểu và giúp mình. thanks

Yêu cầu của mình là xóa hết hàng và để lại các hàng thỏa điều kiện
VD cụ thể là hàng số liệu tương ứng với hàng 7,28 hoăc 29, 53, 52 cho Beam B1
còn B2, B3, B5, B6 là tương tự như vậy mà để lại.

Có nghĩa là với Beam B1 cụ thể là xóa hết còn lại 3 hàng,
hàng 1 là hàng số 7 (khi chưa xóa)
hàng 2 là hàng 28 hoăc 29 (khi chưa xóa)
hàng 3 là hàng 53 (khi chưa xóa)

(Nhưng ô mà mình tô màu xanh va đậm là nhưng ô thỏa điều kiện và ta giữa lại hàng chứa nhưng o đó. còn lại là xóa)
Tương tự Beam B2 cũng còn lại 3 hàng.
Mình đã làm bằng tay đối với Beam B1, B2, B3, Và tô đậm màu xanh các ô thỏa mãn điều kiện ở Beam B4 có ghi chú từng trường hợp. Có lẽ anh ThuNghi giờ sẽ hiểu ý mình. Và mong anh ThuNghi giúp em với. ( chú ý đùng bấm nút ClearData, sẽ xóa hết nhưng ghi chú đó của mình)

Nói thì nhiều cho các bạn dẻ hình dung, chứ tốm lại có 1 câu 1 thôi.
Làm sao cho mỗi phần tử Beam chỉ để lại 3 dòng, có giá trị tuyệt đối lớn nhất ở 3 vị trị: Đầu , Giưu và Cuối.

Anh chi em GPE với!

Làm sao cho mỗi phần tử Beam chỉ để lại 3 dòng, có giá trị tuyệt đối lớn nhất ở 3 vị trị: Đầu , Giưu và Cuối. còn lại là xóa hết.
file gởi kềm ở #3

Yêu Cầu Lọc Theo điều kiện( file gởi kềm trong #1)
Xóa hết các hàng, chỉ để lại những hàng thỏa điều kiện bên dưới
Lấy VD là Beam B1
1. Ở Loc đầu, lấy hàng dữ liệu có M3 giá trị nhỏ nhất (hàng 7 có M3= -6.607)
2. Ở Loc giữa, lấy hàng dữ liệu có M3 giá trị lớn nhất (hàng 28 hoặc 29 cũng được có M3= 3.525)
3. Ở Loc cuối, lấy hàng dữ liệu có M3 giá trĩ nhỏ nhất (hàng 53 có M3= -6.684)
 

File đính kèm

Đã làm được thành công VBA, Mong các bạn giúp nó chạy nhanh hơn.

1. Hướng lập trình của mình đã trình bày trong #17 mình nghỉ đó là hướng làm đơn giản nhất, nhưng lúc đó trình độ của mình thì không biết bắt đầu từ đâu để làm được theo hướng mà mình nghĩ ra. Cả 1 tuần mình mề mò, và phát hiện lệnh
For Each Cell In Range
Thế là việc diệt qua từng Cell đã thực hiện được, nhưng không biết cách nào để tô đậm ô cần tìm... mình lại tốn thêm gần 1 ngày nữa mới tìm ra --> ra rồi vui ko ke siết.

2. Code mình viết đã thực hiện đúng yêu cầu, rất đơn giản, dẻ hiểu, làm việc được vơi bất kỳ Story or Beam, Nhưng vì mình mới học VBA, nên cấu trúc câu lệnh chưa ưu việt, nó chạy như con rùa, nhảy nhót lung tung, Mong các bạn giúp mình làm cho nó chạy ưu việt nhất, và nhanh nhất, vì nếu dữ liệu dài cả 10.000 hàng thì nó chạy đến mấy chục phút lận (thể hiện rõ nhất khi ấn nút ShortData). ngồi chờ mà sỉu luôn. Mình cũng không biết nên định nghĩa các biến như thế nào là hợp lý (Trong code mình không định nghĩa sao nó vẫn chạy ok nên mình để vậy luôn.hihi, cai này thì không biết, phải nhờ anh em thôi)???

3. Nếu có thể các bạn ghi chú cho mình hiểu những lệnh bạn thêm vào có ý nghĩa gì? làm cho Code chạy nhanh hơn ở phần nào? cho mình hiểu với...Thanks các bạn.

4. Mong GPE thu gọn giúp đoạn Code cua minh cho that đơn giản và ngắn lại.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
1./
File này mình làm khi diễn đàn mới ngưng; Mong tác giả topic kiểm chứng lại chút
End Sub[/PHP]

File của bạn không biết đường nào mà Run hết. Mình phải Run nó và thây kết quả, xong mới kiểm tra Code. Code ban viết mình thử chạy mấy cái mà không thấy có tác dụng gì cả? Không hiểu ý bạn??? Ban co thể nói gợi ý hướng đi của Code của bạn được không? Thanks nhiều.
 
Upvote 0
File của bạn không biết đường nào mà Run hết. Mình phải Run nó và thây kết quả, xong mới kiểm tra Code. Code ban viết mình thử chạy mấy cái mà không thấy có tác dụng gì cả? Không hiểu ý bạn??? Ban co thể nói gợi ý hướng đi của Code của bạn được không? Thanks nhiều.
Bạn qua sheets("DaTa"), xóa các cột từ 'N' đến 'Z'
sau đó cho chạy macro XacDinhKhoi sẽ thấy kết quả trích xuất từ sheets("Beam") sang những cột bạn vừa xóa.
Thật ra trong mảco đã có dòng lệnh này; nhưng bạn làm bằng tay sẽ tác dụng hơn!
:-=--=0
 
Upvote 0
1./
File này mình làm khi diễn đàn mới ngưng; Mong tác giả topic kiểm chứng lại chút
End Sub[/PHP]
Mình chưa hiểu lắm về code của bạn, nhưng kết quả ở sheet Data, từ cột N -> S /Sheet Data là không đúng lắm.
1. Vì Theo điều kiện M3min1 ở Loc đầu
M3max ở giữa
M3min2 ở Loc cuối
Thi khi đó Loc phải tăng giá trị từ nhỏ đến lớn VD B1: có Loc 0-3-6, B2: có Loc 0-1.5-3 là OK
nhưng B3 có Loc: 0-2-0 là không đúng rồi. Cho nên giá trị M3 của B3 cũng sai luôn. Số của file bạn là: -1.993, 1.186, -2.251, nhưng thực tế đúng là: -2.251, 1.186, -2.231 (Bạn có thể tham khảo giá trị đúng ở file của minh ở #23)
2. Không thể đẻ hàng tiêu đề cho dữ liệu được vì mỗi lần Run nó xóa hàng N1 đến S1
Khi sữa lại B1 thành B99 chẳn hạn thì nó không cập nhật B99 vào bảng lọc??
hoặc khi dữ liệu có B1 và B12 thì nó lại hiểu B1 và B12 chung là 1, nên số liệu xuất ra 3 hàng chỉ có B1 mà không có B12?

3. Mong bạn hoàn chỉnh VB theo hướng của bạn đã làm, nếu Run Ok thì đây cung là 1 hương giải quyết hay lắm đó. Tối qua mình đã xêm Code của bạn, cũng có chổ hiểu chổ không. Nhất là câu:
PHP:
Set Rng = .Find(what:="B" & CStr(Wf), LookIn:=xlValues)
Set RngM = Rng.Find(what:=dMax, LookIn:=xlValues)
Mình tra trong cuốn sách VBA của Phan Tu Huong, cung không thấy nói đến hàm Find
Mình muốn hiểu câu lệnh Find ??? mà chưa hiểu???Mong cac ban giúp cho mính 1 vidu đơn giản.
 
Lần chỉnh sửa cuối:
Upvote 0
Chúng ta cùng cải tiến 1 macro xem sao nha!

2. Code mình viết đã thực hiện đúng yêu cầu, rất đơn giản, dẻ hiểu, làm việc được vơi bất kỳ Story or Beam, Nhưng vì mình mới học VBA, nên cấu trúc câu lệnh chưa ưu việt, nó chạy như con rùa, nhảy nhót lung tung, Mong các bạn giúp mình làm cho nó chạy ưu việt nhất, và nhanh nhất, vì nếu dữ liệu dài cả 10.000 hàng thì nó chạy đến mấy chục phút lận (thể hiện rõ nhất khi ấn nút ShortData). ngồi chờ mà sỉu luôn. Mình cũng không biết nên định nghĩa các biến như thế nào là hợp lý (Trong code mình không định nghĩa sao nó vẫn chạy ok nên mình để vậy luôn.hihi, cai này thì không biết, phải nhờ anh em thôi)???
3. Nếu có thể các bạn ghi chú cho mình hiểu những lệnh bạn thêm vào có ý nghĩa gì? làm cho Code chạy nhanh hơn ở phần nào? cho mình hiểu với...Thanks các bạn.
4. Mong GPE thu gọn giúp đoạn Code cua minh cho that đơn giản và ngắn lại.

PHP:
' Option Explicit'
Sub InputData()
1 Dim eRow As Long
 
 Application.ScreenUpdating = False
3 Sheets("Etabs").Activate
 eRow = [B65500].End(xlUp).Row
5 Range([A2], Cells(eRow, "D")).Copy Destination:=Sheets("Beam").[A6]
 Range([F2], Cells(eRow, "F")).Copy Destination:=Sheets("Beam").[E6]
7 Range([J2], Cells(eRow, "J")).Copy Destination:=Sheets("Beam").[F6]
 Sheets("Beam").Select
9 Range([A6], Cells(eRow + 4, "F")).Select
 Selection.Sort Key1:=[B6], _
   Order1:=xlAscending, Key2:=[D6], Order2:=xlAscending
End Sub
Chúng ta cùng bàn luận macro trên, (cái này tôi muốn bạn thay cho cái của bạn!)
Dòng lệnh trên cùng tôi đã vô hiệu hóa bằng dấu nháy đơn trước dòng lệnh
Dòng lệnh đó yêu cầu tất tần tật các biến phải được khai báo tường minh (đầy đủ & tường tận). Điều này mình cho là rất tốt cho những người tự học VBA như chúng ta.
Tuy nhiên tại thời điểm này, chúng ta vô hiệu hóa nó, vì liên quan đến các macro khác bên dưới của bạn.
D1: Khai báo biến eRow có kiểu Long; Tại sao?
Thứ nhất, biến không nên là 1 chữ cái, 1 chữ cái chứa rất ít thông tin; Tôi khai dài như vậy (4 chữ) nhưng ta có thể nhớ là biến này tôi sẽ dùng để lưu giữ giá trị dòng cuối cùng chưa dữ liệu của trang tính. Tất nhiên bạn & tôi đều có thể việt hóa tên biến này, VD: DgCuoi, CDong, DgC . . . Tất cả các tên như vậy làm chúng ta liên tưởng hơn là 1 chữ n vô tri vô giác.
Thêm nữa, tên biến nên có ít nhất 2 ký tự (gồm cả 1 ký số), trong đó nên có từ viết hoa xen lẫn từ viết thường. Việc này để làm gì?
Để tận dụng tiện ích có sẵn trong VBA khi ta viết dòng lệnh không sai sót ngữ pháp. Khi khai tên là vậy, nhưng trong quá trình viết dòng lệnh, ta cứ đánh toàn chữ thường (hoặc toàn chữ in) VBA sẽ chỉ cho ta 1 cách gián tiếp tên biến nào ta nhập sai.
Thứ hai, Tại sao kiểu là Long, mà không là kiểu khác, như Integer, Double, . . . Qui định kiểu của biến nào là do ta sẽ dùng nó vô việc gì; Biến để chứa số dòng trên trang tính thì phải là Long, vì E2003 có tới 65536 dòng trên 1 trang tính; Nếu khai báo dưới hơn có khi bị báo lỗi vào 1 ngày đẹp trời nào đó, lúc đó DL rất nhiều (vượt kiểu Integer), khi đó dễ làm ta phát hoảng, vì mới hôm qua vẫn bình thường, mà hôm nay báo lỗi. Rất nhiều khi, chúng ta cũng không rõ lỗi từ đâu.
D2: Dòng lệnh này đễ màn hình khỏi lắc lư; Rất nhiều người còn nói là nó tăng tốc chương trình. Chúng ta nên tin họ.
D3 là của bạn;
D4: Giá trị dòng cuối chứa DL (dữ liệu). Điều này bạn có thể tiếp thu từ bộ thu macro.
Bạn thử thu macro với các động tác sau:
* Chọn [B65535]
* Bấm tổ hợp 2 fím Ctrl & [mũi tên lên]
D4 đảm bảo rằng chúng ta tới dòng cuối của cột 'B' chứa dữ liệu
Các dòng lệnh của bạn, cũng đáng tin, nhưng chỉ đáng tin với CSDL của bạn sản sinh ra mà thôi. (Tại sao ư? - Bạn thử tìm hiểu 1 thời gian xem. . .)
3 dòng kế tiếp sau D4 là chép 3 vùng cần thiết từ trang tính này sang trang tính kia;
Hai dòng cuối là của bạn; Tất nhiên mình có sửa 1 tẹo, ở chổ địa chỉ ô; Một khi ta xác định ô rõ ràng rồi, thì không nên trừu tượng hóa nó làm gì. Để sau này chúng ta đỡ tốn thời gian vì nó.

Chúc vui!
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
PHP:
D4 đảm bảo rằng chúng ta tới dòng cuối của cột 'B' chứa dữ liệu
Các dòng lệnh của bạn, cũng đáng tin, nhưng chỉ đáng tin với CSDL của bạn sản sinh ra mà thôi. (Tại sao ư? - Bạn thử tìm hiểu 1 thời gian xem. . .)
3 dòng kế tiếp sau D4 là chép 3 vùng cần thiết từ trang tính này sang trang tính kia;
Hai dòng cuối là của bạn; Tất nhiên mình có sửa 1 tẹo, ở chổ địa chỉ ô; Một khi ta xác định ô rõ ràng rồi, thì không nên trừu tượng hóa nó làm gì. Để sau này chúng ta đỡ tốn thời gian vì nó. 
 [/QUOTE]
1. Mình có thể hiểu ý bạn. nếu dùng 
[COLOR="#ff00ff"]eRow = [B65500].End(xlUp).Row[/COLOR]
Thì ta sẽ từ dưới di lên đến Cells cuối cùng của dữ liệu, điều này tránh trường hộp dữ liệu bị ngắt quản ở giữa (nghĩa là khi dữ liệu đột xuất có dòng trống). Khi đó [COLOR="#ff00ff"].End(xlDown).Row[/COLOR] sẽ đến đoạn ngắt đó mà không đến được cuối Dữ liệu (Không biết có đúng với ý bạn không?).
2. Đoạn InputData có thể xêm là đã gọn hơn rồi. Mong các bạn làm gọn Code nút Nut FilterData , ShortData, ClearData. [B][COLOR="#ff00ff"]Phứt tạp và dài dòng nhất là FilterData. Còn chạy chậm nhất là ShortData.[/COLOR][/B]
File gởi kềm ở bài [B][COLOR="Magenta"]#23[/COLOR][/B]
 
Lần chỉnh sửa cuối:
Upvote 0
Anh HYen17 ơi, em xin trình bày hướng em làm bài của pmhoang như sau, anh thấy giải thuật có hợp lý không nhé.
1/ Từ cột B tạo ra danh mục Beam duy nhất, và sort theo B1, B2, B..., B11, B12...
2/ Duyệt qua DMBeam, dùng Advance Filter (AV) => chi tiết theo Beam=iBeam, sort chi tiết này theo Loc.
3/ Tìm MaxLoc (dòng cuối), MinLoc (dòng đầu) => EndLocDau (MaxLoc/4) và FirstLocCuoi (MaxLoc/4*3). => Vị trí (dòng) của thông số trên. => KqRng.
4/ Từ KqRng => min của M3, Max M3 tùy theo điều kiện lọc.
5/ Tìm vị trí min của M3, Max M3 theo KqRng => dòng min của M3, Max M3, => gán vào Beam.
Ý tưởng là vậy như mà triển khai thấy công phú quá.
Nếu dùng for i hay For eachCell thì dễ hiểu hơn như mà sẽ chậm hơn.
Anh cụ thể theo phương án này hộ em với.
Nhờ có bài này mà em mới nhớ là AF có thể hiểu B1 và B11 như nhau. (may mà phát hiện, mặc dù đã có bài nói về vấn đề này).
Cám ơn Anh nhiều.
 
Upvote 0
Hỏi các bạn về giải thuật của mình, Các bạn cho ý kiến cái.
Mình đinh ninh rằng, nếu hiểu đúng yêu cầu tác giả thì giải thuật của mình không kém ai về tốc độ.
* Tạo vòng lặp tìm lần lượt các B(i). Sau mỗi lần tìm sẽ có 2 chỉ số dòng của đầu & cuối
vùng của Beam thứ (i). Tận dụng được ưu điểm về tốc độ của phương thức FIND()
* Sau khi ta có vùng này, đem đến macro khác để xử lý nó, gồm các công đoạn:
- Tìm Giá trị Max trong vùng nhờ hàm của Excel
- Tìm ô/dòng chứa giá trị Max này - lại nhờ FIND()
(Tiếp sau tác giả còn cho sai; Mình cho là mình chưa hiểu đúng yêu cầu)
- Tìm cực tiểu trong khoảng từ ô đầu tiên của vùng cho đến giá trị Max nêu trên - cũng nhờ hàm Min trong excel;
- Xác định dòng chứa dữ liệu Min này - bằng FIND()
- Chép 2 dòng này sang sheet mới
- Tìm cực tiểu trong đoạn dưới còn lại
- Xác định dòng tương ứng (bằng FIND()) & chép sang nơi mới
(Quá trình được lặp cho đến hết số Beam)

Các bạn chỉ cho mình, rằng mình chưa hiểu đúng chổ nào được không?
Xin cảm ơn các bạn trước nha!
 
Upvote 0
Nhưng vì mình mới học VBA, nên cấu trúc câu lệnh chưa ưu việt, nó chạy như con rùa, nhảy nhót lung tung, Mong các bạn giúp mình làm cho nó chạy ưu việt nhất, và nhanh nhất, . . .
3. Nếu có thể các bạn ghi chú cho mình hiểu những lệnh bạn thêm vào có ý nghĩa gì? làm cho Code chạy nhanh hơn ở phần nào? cho mình hiểu với...Thanks các bạn.

4. Mong GPE thu gọn giúp đoạn Code cua minh cho that đơn giản và ngắn lại.
Mình cho rằng macro này chỉ 1 dòng lệnh duy nhất cũng OK
PHP:
'Nut ClearData --> OK'
Sub ClearData()
  Range("A6").Select
  Selection.End(xlDown).Select
  n = ActiveCell.Row
  Range(Cells(6, "A"), Cells(n, "H")).Select
  Selection.Clear
End Sub
Ví dụ nha:
Mã:
[B]Sub CleaRegion()[/B] 
    Range([A6], [H65500].End(Xlup)).Clear
[B]End Sub[/B]
Bạn có thể dùng lệnh MsgBox Range([A6], [H65500].End(Xlup)).Address để chiêm nghiệm
 
Upvote 0
Mình cho rằng macro này chỉ 1 dòng lệnh duy nhất cũng OK
PHP:
Ví dụ nha:
[code] 
[B]Sub CleaRegion()[/B] 
    Range([A6], [H65500].End(Xlup)).Clear
[B]End Sub[/B]
[/code]
Bạn có thể dùng lệnh [B]MsgBox Range([A6], [H65500].End(Xlup)).Address[/B] để chiêm nghiệm[/quote]
 
thêm application.ScreenUpdating=false  
cho nhanh một chút
 
Upvote 0
Hỏi các bạn về giải thuật của mình, Các bạn cho ý kiến cái.
Mình đinh ninh rằng, nếu hiểu đúng yêu cầu tác giả thì giải thuật của mình không kém ai về tốc độ.
* Tạo vòng lặp tìm lần lượt các B(i). Sau mỗi lần tìm sẽ có 2 chỉ số dòng của đầu & cuối
vùng của Beam thứ (i). Tận dụng được ưu điểm về tốc độ của phương thức FIND()
1. Giải thuật của bạn phải công nhận là làm việc rất nhanh, Có thể nói hiện giờ chưa có Code nào qua mặt, Mong bạn bổ sung thêm để nó Run Ok, Mình rất hi vọng về Giải thuật của bạn. Mong sẽ nhận được sản phẩm hoàn chỉnh. (vì Cái Find() mình chưa hiểu hiết nên không biết đường sửa chữa thêm vào Code của bạn, Sorry...)

2. Mình chưa hiểu về cách dùng Find()???. Mong bạn giúp mình 1 vd đơn giản mình sẽ chỉ ra chổ sai cho bạn. Còn bây giờ mình kiểm tra thủ công bằng cách cho xuất ra các giá trị đầu và cuối Beam của từng loại Beam thì mình thấy có chổ sai, đây là kết quả lần lược khi Run Code của bạn.
Rw1=3, Rw2=50 -> TR/B1 (Đúng) - Là số dòng đầu và cuối của B1 Thuộc Story TR
Rw1=51, Rw2=74 -> Beam TR/B2 - Đúng
75, 106 -> TR/B3 - Đúng
107, 154 -> TR/B4 - Đúng
155, 202 -> TR/B5 - Đúng
203, 267 -> TR/B6 và LAU1/B6 - Sai - vì bạn đã chọn 1 lúc 2 Loại Beam để xuất ra 3 giòng Mmin1, Mmax, Mmin2 - Kết quả xuất ra sẽ thiếu Beam LAU1/B6 (thiếu)
268, 399 -> LAU1/B7 , LAU1/B9, LAU1/B12 nó hiểu là 1, chon nên chỉ xuất ra kết quả là LAU1/B7, thiếu đi B9, B12 - Bạn có thể xêm kết quả Run của Code của bạn sẽ rõ.


Nội dung và yêu cầu có ghi đầy đủ và rõ ràng trong file gởi kềm ở Bài #1. Cảm ơn sự quang tam của Anh SA_DQ, và các bạn.
File DieukienLoc là file gốc chưa lọc
File DieukienLoc - ghichu2 là file đã tô mà xanh nhưng ô thỏa diều kiện cho bạn dẻ hình dung.
còn file ở BÀi #23 là file đúng, Bạn Ấn nút Inputdata (nhập Data vào và Sort theo Beam và Loc) -> FilterData (Tô màu đỏ và đậm nhưng ô thỏa điều kiện) -> Shortdata (Rút ngắn mỗi loại Beam còn lại 3 hàng) sẽ ra kết quá đúng, Nếu kết quả của file bạn làm ra như thế là OK (Ghi chú: File DieuKienLoc-PMH chỉ cho ra kết quả đúng còn Run thì như con rùa, cần các bạn hoàn chỉnh thêm)
 
Lần chỉnh sửa cuối:
Upvote 0
Em xin trình bày hướng làm bài như sau,
1/ Từ cột B tạo ra danh mục Beam duy nhất, và sort theo B1, B2, B..., B11, B12...
2/ Duyệt qua DMBeam, dùng Advance Filter (AV) => chi tiết theo Beam=iBeam, sort chi tiết này theo Loc.
3/ Tìm MaxLoc (dòng cuối), MinLoc (dòng đầu) => EndLocDau (MaxLoc/4) và FirstLocCuoi (MaxLoc/4*3). => Vị trí (dòng) của thông số trên. => KqRng.
4/ Từ KqRng => min của M3, Max M3 tùy theo điều kiện lọc.
5/ Tìm vị trí min của M3, Max M3 theo KqRng => dòng min của M3, Max M3, => gán vào Beam.
Ý tưởng là vậy như mà triển khai thấy công phú quá.
Mình xin đề xuất sửa phương án của ThuNghi xíu; Nếu chúng ta thỏa thuận được phương án, mình sẽ biến nó thành hiện thực:

(Coi như dữ liệu đã được xếp theo cột 'B' (Beam))
Khai báo 2 biến DDau & DCuoi kiểu Long (để ghi dòng đầu & dòng cuối của 1 Beam cụ thể nào đó khi dùng vòng lặp duyệt theo cột 'B') & 1 biến chuỗi tạm để ghi nhận 1 khi Beam thay đổi từ dòng trên xuống dòng dưới
Tất nhiên vào đầu vòng lặp DDau = Row1 (=6)
Khi Beam chuyển từ B10 =>> B110 thì ta có vùng Range("B" & DDau & ":B" & DCuoi)
Ta đem vùng này sang macro khác xử lý, như sau:
* Tìm giá trị max trong vùng nhờ hàm của excel
* Tìm địa chỉ ô ứng với giá trị max này (MaxAddress)
* Tìm Giá trị Min trong vùng thuộc Range("B" & DDau & ":B" & MaxAddress.Row
* Lại tìm địa chỉ ứng với giá trị Min1
(+) Chép hai dòng tìm được sang Sheet mới
Lặp lại lần nữa để tìm Min2 & lại chép dòng thứ ba sang sheet mới

(Do các file ban đầu tác giả đưa ra các Beam liên tục nên mình tạo hướng đi sai;)

Mong tin của ThuNghi về vấn đề này!
 
Upvote 0
Mình xin đề xuất sửa phương án của ThuNghi xíu; Nếu chúng ta thỏa thuận được phương án, mình sẽ biến nó thành hiện thực:

1. Phương án của bạn giống như phương án mình đã làm trong file ở bài #23 (bạn có thể xêm Code trong file), nhưng mình không biết tận dụng được các hàm Excel và MaxAddress cho nên cách viết của mình rất là dài.

Chú ý: Có thể trong dữ liệu có 2 Beam trùng tên, nhưng thực tế không phải là dữ liệu sai. mình ví dụ ở Story TR ta có Beam B6, Lên Story LAU1 ta lại có Beam B6, điều này thực tế không có sai. vì vậy khi thay đồi vùng chọn để tính từng loại, Beam này sang Beam khác phải thỏa mãn OR (Beam thay doi, Story thay đổi).

2. Thân chào. Mong gốp ý của HYen17 va ThuNghi
 
Upvote 0
Mình xin đề xuất sửa phương án của ThuNghi xíu; Nếu chúng ta thỏa thuận được phương án, mình sẽ biến nó thành hiện thực:

(Coi như dữ liệu đã được xếp theo cột 'B' (Beam))
Khai báo 2 biến DDau & DCuoi kiểu Long (để ghi dòng đầu & dòng cuối của 1 Beam cụ thể nào đó khi dùng vòng lặp duyệt theo cột 'B') & 1 biến chuỗi tạm để ghi nhận 1 khi Beam thay đổi từ dòng trên xuống dòng dưới
Tất nhiên vào đầu vòng lặp DDau = Row1 (=6)
Khi Beam chuyển từ B10 =>> B110 thì ta có vùng Range("B" & DDau & ":B" & DCuoi)
Ta đem vùng này sang macro khác xử lý, như sau:
* Tìm giá trị max trong vùng nhờ hàm của excel
* Tìm địa chỉ ô ứng với giá trị max này (MaxAddress)
* Tìm Giá trị Min trong vùng thuộc Range("B" & DDau & ":B" & MaxAddress.Row
* Lại tìm địa chỉ ứng với giá trị Min1
(+) Chép hai dòng tìm được sang Sheet mới
Lặp lại lần nữa để tìm Min2 & lại chép dòng thứ ba sang sheet mới
Em cũng nghĩ giải pháp như vậy nhưng chưa hiểu ý tác giả là: tìm Min1 và Min2 trong khỏang loc như thế nào.
Ví dụ ta có: Beam=X100 có LocMin là 0, LocMax là 12.
Vậy phải làm rõ trong khỏang Loc nào => Min1, và =>Min2
Em nghĩ như sau: Lọc chia thành 3 phần (có thể ứng với Beam=iBeam có thể có xuất hiện 2 lần Loc=3 or =1
- Trong khỏang 0<=Loc<=LocMax/4 => Min1
- Trong khỏang LocMax/4*3<=Loc<=LocMax => Min2
- Trong khỏang LocMax/4<=Loc<=LocMax/4*3 => Max.
Giải quyết OK vấn đề này thì sẽ đơn giản hơn. Em thắc mắc mấy dấu "=" hay "<=" hay "<"
 
Upvote 0
1
Chú ý: Có thể trong dữ liệu có 2 Beam trùng tên, nhưng thực tế không phải là dữ liệu sai. mình ví dụ ở Story TR ta có Beam B6, Lên Story LAU1 ta lại có Beam B6, điều này thực tế không có sai. vì vậy khi thay đồi vùng chọn để tính từng loại, Beam này sang Beam khác phải thỏa mãn OR (Beam thay doi, Story thay đổi).
Vậy lúc này thì xác định lọc theo Beam hay Beam và Story
Giả dụ:
Beam= B6, Story là LAU1 có maxLoc là 6
Beam= B6, Story là TR có maxLoc là 8
Lúc này là 2 phần khác nhau hay sao.
 
Upvote 0
Mình xin đề xuất sửa phương án của ThuNghi xíu; Nếu chúng ta thỏa thuận được phương án, mình sẽ biến nó thành hiện thực:

(Coi như dữ liệu đã được xếp theo cột 'B' (Beam))
Khai báo 2 biến DDau & DCuoi kiểu Long (để ghi dòng đầu & dòng cuối của 1 Beam cụ thể nào đó khi dùng vòng lặp duyệt theo cột 'B') & 1 biến chuỗi tạm để ghi nhận 1 khi Beam thay đổi từ dòng trên xuống dòng dưới
Tất nhiên vào đầu vòng lặp DDau = Row1 (=6)
Khi Beam chuyển từ B10 =>> B110 thì ta có vùng Range(&quot;B&quot; & DDau & &quot;:B&quot; & DCuoi)
Ta đem vùng này sang macro khác xử lý, như sau:
* Tìm giá trị max trong vùng nhờ hàm của excel
* Tìm địa chỉ ô ứng với giá trị max này (MaxAddress)
* Tìm Giá trị Min trong vùng thuộc Range(&quot;B&quot; & DDau & &quot;:B&quot; & MaxAddress.Row
* Lại tìm địa chỉ ứng với giá trị Min1
(+) Chép hai dòng tìm được sang Sheet mới
Lặp lại lần nữa để tìm Min2 & lại chép dòng thứ ba sang sheet mới

(Do các file ban đầu tác giả đưa ra các Beam liên tục nên mình tạo hướng đi sai;)

Mong tin của ThuNghi về vấn đề này!
Theo hướng chuẩn rồi đó. Cụ thể là thế này
Theo boyxin: thuật toán phải thế này,
Tìm vị trí đầu của mỗi Beam Vt1
Tìm vị trí cuối của mỗi Beam Vt2

chuyển sang code khác thực hiện ứng với mỗi loại Beam (từ dưới lên)
Tìm MAX(Vt1:Vt2) => Vtmax

Tìm MIN(Vt1:Vtmax) => Vtmin1

Tìm MIN(Vtmax:Vt2) => Vtmin2
Giữ lại các record ... tìm được

Next
đã thực hiện bằng công thức ra kết quả chuẩn nhưng có điều với số lương record nhiều thì tốc độ hạn chế
 
Lần chỉnh sửa cuối:
Upvote 0
Mình chưa hiểu lắm về code của bạn, Tối qua mình đã xêm Code của bạn, cũng có chổ hiểu chổ không. Nhất là câu:
PHP:
Set Rng = .Find(what:="B" & CStr(Wf), LookIn:=xlValues)
Set RngM = Rng.Find(what:=dMax, LookIn:=xlValues)
Mình tra trong cuốn sách VBA của Phan Tu Huong, cung không thấy nói đến hàm Find
Mình muốn hiểu câu lệnh Find ??? mà chưa hiểu???Mong cac ban giúp cho mính 1 vidu đơn giản.
Bạn đến đây tham khảo tạm
http://www.giaiphapexcel.com/forum/showthread.php?t=12301

Nhưng nó không phải là hàm, mà là phương thức của VBA

Trong phần giúp đỡ của VBA, phương thức được giải thích như sau:

Finds specific information in a range, and returns a Range object that represents the first cell where that information is found. Returns Nothing if no match is found. Doesn’t affect the selection or the active cell.
For information about using the Find worksheet function in Visual Basic, see Using Worksheet Functions in Visual Basic.
expression.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)
expression Required. An expression that returns a Range object.
What Required Variant. The data to search for. Can be a string or any Microsoft Excel data type.
After Optional Variant. The cell after which you want the search to begin. This corresponds to the position of the active cell when a search is done from the user interface. Note that After must be a single cell in the range. Remember that the search begins after this cell; the specified cell isn’t searched until the method wraps back around to this cell. If you don’t specify this argument, the search starts after the cell in the upper-left corner of the range.
LookIn Optional Variant. The type of information.
LookAt Optional Variant. Can be one of the following XlLookAt constants: xlWhole or xlPart.
SearchOrder Optional Variant. Can be one of the following XlSearchOrder constants: xlByRows or xlByColumns.
SearchDirection Optional XlSearchDirection. The search direction.
XlSearchDirection can be one of these XlSearchDirection constants.xlNext defaultxlPrevious

MatchCase Optional Variant. True to make the search case sensitive. The default value is False.
MatchByte Optional Variant. Used only if you’ve selected or installed double-byte language support. True to have double-byte characters match only double-byte characters. False to have double-byte characters match their single-byte equivalents.
SearchFormat Optional Variant. The search format.
Remarks

The settings for LookIn, LookAt, SearchOrder, and MatchByte are saved each time you use this method. If you don’t specify values for these arguments the next time you call the method, the saved values are used. Setting these arguments changes the settings in the Find dialog box, and changing the settings in the Find dialog box changes the saved values that are used if you omit the arguments. To avoid problems, set these arguments explicitly each time you use this method.
You can use the FindNext and FindPrevious methods to repeat the search.
When the search reaches the end of the specified search range, it wraps around to the beginning of the range. To stop a search when this wraparound occurs, save the address of the first found cell, and then test each successive found-cell address against this saved address.
To find cells that match more complicated patterns, use a For Each...Next statement with the Like operator. For example, the following code searches for all cells in the range A1:C5 that use a font whose name starts with the letters Cour. When Microsoft Excel finds a match, it changes the font to Times New Roman.
For Each c In [A1:C5] If c.Font.Name Like "Cour*" Then c.Font.Name = "Times New Roman" End IfNext
Example

This example finds all cells in the range A1:A500 on worksheet one that contain the value 2 and changes it to 5.
PHP:
With Worksheets(1).Range("a1:a500") 
    Set c = .Find(2, lookin:=xlValues) 
    If Not c Is Nothing Then 
         firstAddress = c.Address 
         Do 
             c.Value = 5 
             Set c = .FindNext(c) 
         Loop While Not c Is Nothing And c.Address <> firstAddress 
     End If 
End With
:-=
 
Lần chỉnh sửa cuối:
Upvote 0
To ThuNghi & BoyXyn

Hai bạn chạy thử macro sau & cho ý kiến, giúp nha!
PHP:
Option Explicit
Sub DestinationBlock()
 Dim eRow As Long, fRow As Long, lRow As Long, sRow As Long
 Dim rRng As Range, Rng As Range
 Dim GPE_Address As String
 
 Sheets("Beam").Select:                   Application.ScreenUpdating = False
 eRow = [B65432].End(xlUp).Row
 Sheets("Data").Select:                   Range([a2], Cells(eRow, "H")).Clear
 Sheets("Beam").Select
 
 With Sheets("Beam").Range("B6:B" & eRow)
   sRow = 6
   Do
      Set Rng = .Find(what:=Cells(sRow, "b"), LookIn:=xlValues, LookAt:=xlWhole)
      If Not Rng Is Nothing Then
         Set rRng = Rng
         GPE_Address = Rng.Address
         Do
            Set rRng = Union(rRng, Rng)
            Set Rng = .FindNext(Rng)
         Loop While Not Rng Is Nothing And Rng.Address <> GPE_Address
      End If
      If Not rRng Is Nothing Then
         MsgBox rRng.Offset(, -1).Resize(, 6).Address, , rRng.Rows.Count + sRow
         sRow = rRng.Rows.Count + sRow
      Else:                               End If
      If sRow > eRow Then Exit Do
   Loop
 End With
 End Sub
:-=--=0}}}}}@$@!^%
(Mới nữa chặng thôi; nhưng nếu đúng thì sẽ là 10% còn lại để đến đích mà thôi
Vì cái macro thứ hai ở trên sẽ xài được, không việc gì âu lo!)
 
Upvote 0
Vậy lúc này thì xác định lọc theo Beam hay Beam và Story
Giả dụ:
Beam= B6, Story là LAU1 có maxLoc là 6
Beam= B6, Story là TR có maxLoc là 8
Lúc này là 2 phần khác nhau hay sao.

1. Số liệu nguyên thủy là luôn giữa nguyên ở Sheet Etabs (Đó là từ Phần mền xuất ra - nó luôn liên tục từ hàng trên xuống hàng dưới không có ngắt quản)
2. Ta InputData từ Sheet Etabs vào Sheet Beam, Ở Sheet Beam ta Sort nó theo 3 điều kiện 1. Story 2.Beam 3.Loc
Khi đó mỗi Beam vẫn đảm bảo có Lóc đi từ nhỏ đến lớn. Mình sẽ sớm Up lên 1 file có Data Chuẩn có đủ mọi trường hợp cụ thể trong file cho các bạn tham khảo. (Đã upfile lên ở bài #45)
Than chào
....
Thân chào.
Em cũng nghĩ giải pháp như vậy nhưng chưa hiểu ý tác giả là: tìm Min1 và Min2 trong khỏang loc như thế nào.
1. Cái này thì thành thật Sorry anh ThuNghi. Vì khi mới Upfile lên hỏi GPE, em không biết nên hỏi từ đâu. Trong file em có vẽ cả cái biểu đồ biến đổi của M3, theo biểu đồ thì M3 sẽ di từ nhỏ ở Lóc đầu tiên, sau đó tăng lên đến M3 Max ở giữa Loc (Ở vùng giữa thôi, chứ không chắc là ở chính giữa) và đến gần cuối Lóc thì nhỏ lại.
Mà mình thì chỉ cần 3 giá trị, 1. M3min1, M3max, M3min2, cho nên khi anh ThuNghi hỏi em là cụ thể lấy M3min1 ở vùng nào, em mới vd là khoảng 1/4 vì thường là như thế, vì lúc đó em đâu có biết hướng đi của bài toán này đâu.
Sau đó ở các bài #2, #3 gì đó em đã nghĩ ra hướng đi. và có phát biểu hướng đi. nhưng thấy chưa có bạn nào đi theo hương đó. Em phải tự lực cách sinh..hihi...

2. Cái vụ này thì làm theo cách 1/4 cũng cho ra kết quả như làm theo cách của HYen17, (vì nhìn vào biểu đồ thay đổi của M3 là suy ra 2 cách se cho ra cùng kết quả, Biểu đồ trong file ở bài đầu tiên #1).
3. Mong ThuNghi Sorry cho minh.
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi lấy thử 1 Beam=B6.
Bạn hãy cho ra 2 kết quả theo Sheet1 và Sheet2. Nếu có thể vẽ đồ thị M3 theo Loc. Tôi không hiểu làm thế nào vẽ đồ thị khi có 2 lần Loc=0.
Và nếu có thể cho biết tại sao chọn những M3.
Phải hiểu thì làm mới được. Từ Code của bạn khó suy diễn.
 

File đính kèm

Upvote 0
Web KT

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

Back
Top Bottom