[Nhờ giúp đỡ] Trả về giá trị sơ cấp xuất hiện đầu tiên trong dữ liệu gốc (1 người xem)

Liên hệ QC

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

Tuấn Giang

Thành viên chính thức
Tham gia
19/7/06
Bài viết
80
Được thích
24
Chào các anh chị,

Mình có một file dữ liệu như attachment gồm 2 Sheet: Data và Report, trong đó có Nhiều Table dữ liệu khác nhau.

Yêu cầu là: Tìm giá trị thứ cấp đầu tiên xuất hiện trong Table thuộc dữ liệu gốc và trả về giá trị đó tại Report.

PS: Do rất khó để giải thích yêu cầu cụ thể mà không có minh họa nên mình xin phép giải thích chi tiết yêu cầu trong file đính kèm, nhờ các anh chị giúp đỡ xử lý vấn đề trong thời gian sớm nhất.

Xin chân thành cảm ơn!
 

File đính kèm

1. Công thức E6 sheet Data:
=IF(D6<>Report!B$2;"";ROW())

Fill xuống và copy cho các cột J, O, T, ...

2. Công thức B6 sheet Report:
=IFERROR(OFFSET(Data!E$5;MATCH(SMALL(Data!E$5:E$39;Report!A6);Data!E$5:E$39;0);-4);"")

Fill xuống và copy cho các cột G, L, Q, ...
 
Lần chỉnh sửa cuối:
Upvote 0
1. Công thức E6 sheet Data:
=IF(D6<>Report!B$2;"";ROW())

Fill xuống và copy cho các cột J, O, T, ...

2. Công thức B6 sheet Report:
=IFERROR(OFFSET(Data!E$5;MATCH(SMALL(Data!E$5:E$39;Report!A6);Data!E$5:E$39;0);-4);"")

Fill xuống và copy cho các cột G, L, Q, ...
Hình như hổng phải "dzậy" Thầy ơi, có thể kết quả ở Table 1, sơ cấp 2 gồm các Thứ cấp: 1 [A9], 2 [A32], 3 [A17], 5 [A19], 7 [A36] hay sao í. Làm bằng công thức cũng được nhưng sợ hiểu chưa đúng nên.......chờ. Híc
 
Upvote 0
1. Công thức E6 sheet Data:
=IF(D6<>Report!B$2;"";ROW())

Fill xuống và copy cho các cột J, O, T, ...

2. Công thức B6 sheet Report:
=IFERROR(OFFSET(Data!E$5;MATCH(SMALL(Data!E$5:E$39;Report!A6);Data!E$5:E$39;0);-4);"")

Fill xuống và copy cho các cột G, L, Q, ...
----------------------------
Cảm ơn bác,

Làm bằng công thức thì dễ rồi, nhưng dữ liệu của em rất lớn, có gần 100 cái Table như vẫn, và số dòng của mỗi Table cũng khoảng > 500 dòng. Nếu sử dụng công thức thì file sẽ rất nặng. Em muốn dùng VBA để chạy, nhưng không hiểu sao code em viết nó chạy cũng không được chuẩn.

Em muốn tìm các thứ cấp ứng với cột A (G...), xuất hiện đầu tiên và lấy giá trị đó sang REPORT. Mọi người xem thử code và tối ưu giúp nhé.

Thanks,
 

File đính kèm

Upvote 0
----------------------------
Cảm ơn bác,

Làm bằng công thức thì dễ rồi, nhưng dữ liệu của em rất lớn, có gần 100 cái Table như vẫn, và số dòng của mỗi Table cũng khoảng > 500 dòng. Nếu sử dụng công thức thì file sẽ rất nặng. Em muốn dùng VBA để chạy, nhưng không hiểu sao code em viết nó chạy cũng không được chuẩn.

Em muốn tìm các thứ cấp ứng với cột A (G...), xuất hiện đầu tiên và lấy giá trị đó sang REPORT. Mọi người xem thử code và tối ưu giúp nhé.

Thanks,

Với hằng trăm tables thì chỉ có phần mềm chuyên về CSDL (Access, SQL Server, + Crystal Report chẳng hạn) thì mới có thể tối ưu.
 
Upvote 0
Chào các anh chị,

Mình có một file dữ liệu như attachment gồm 2 Sheet: Data và Report, trong đó có Nhiều Table dữ liệu khác nhau.

Yêu cầu là: Tìm giá trị thứ cấp đầu tiên xuất hiện trong Table thuộc dữ liệu gốc và trả về giá trị đó tại Report.

PS: Do rất khó để giải thích yêu cầu cụ thể mà không có minh họa nên mình xin phép giải thích chi tiết yêu cầu trong file đính kèm, nhờ các anh chị giúp đỡ xử lý vấn đề trong thời gian sớm nhất.

Xin chân thành cảm ơn!

Bạn thử code sau
Mã:
Sub Test()
Dim c, d,f,m p, s, Table
On Error Resume Next
Set p = Sheets("Data").UsedRange
Set s = Sheets("Report").UsedRange
Set c = Sheets("Report").[B2]
Do
Set Table = Sheets("Data").Cells.Find(c.Offset(1, -1), LookAt:=xlWhole)
Set d = p.Columns(Table.Column + 3).Find(c, LookAt:=xlWhole)
If Not d Is Nothing Then
f = d.Address
Do
m = WorksheetFunction.Match(d.Offset(1), Sheets("Report").Columns(c.Column - 1), 0)
If s.Columns.Cells(m, c.Column) = "" Then s.Columns.Cells(m, c.Column) = d.Offset(1, -3).Value
Set d = p.Columns(Table.Column + 3).FindNext(d)
Loop While Not d Is Nothing And d.Address <> f
End If
Set c = c.End(xlToRight)
Loop Until c = ""
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn thử code sau
Mã:
Sub Test()
Dim c, d,f,m p, s, Table
On Error Resume Next
Set p = Sheets("Data").UsedRange
Set s = Sheets("Report").UsedRange
Set c = Sheets("Report").[B2]
Do
Set Table = Sheets("Data").Cells.Find(c.Offset(1, -1), LookAt:=xlWhole)
Set d = p.Columns(Table.Column + 3).Find(c, LookAt:=xlWhole)
If Not d Is Nothing Then
f = d.Address
Do
m = WorksheetFunction.Match(d.Offset(1), Sheets("Report").Columns(c.Column - 1), 0)
If s.Columns.Cells(m, c.Column) = "" Then s.Columns.Cells(m, c.Column) = d.Offset(1, -3).Value
Set d = p.Columns(Table.Column + 3).FindNext(d)
Loop While Not d Is Nothing And d.Address <> f
End If
Set c = c.End(xlToRight)
Loop Until c = ""
End Sub

Cảm ơn bạn nhiều,


Code của bạn rất hay. Tuy nhiên, số lượng table của mình rất lớn (khoảng gần 100 bảng và mỗi có có trên 500 dòng), mình dùng code của bạn chạy thử thì kết quả của bảng thứ 6 trở đi lại không chính xác. Bạn có thể giúp mình thêm nữ được không?
 
Upvote 0
Bạn thử với macro sau

PHP:
Option Explicit
Sub TimNgayThuCap()
 Dim Sh As Worksheet, Rng As Range, sRng As Range
 Dim Col As Integer, J As Integer, Rws As Long
 Dim fAdd As String

 Sheets("Report").Select:           Set Sh = ThisWorkbook.Worksheets("Data")
 Col = Sheets("Report").UsedRange.Columns.Count
 For J = 2 To Col Step 5
    Set Rng = Sh.Range(Sh.Cells(5, J), Sh.Cells(5, J).End(xlDown)).Offset(, 2)
    Rws = Rng.Rows.Count
    Cells(6, J).Resize(Rws).ClearContents
    Set sRng = Rng.Find(Cells(2, J).Value, , xlFormulas, xlWhole)
    If Not sRng Is Nothing Then
        fAdd = sRng.Address
        Do
            Cells(Rws, J).End(xlUp).Offset(1).Value = sRng.Offset(1, -3).Value
            Set sRng = Rng.FindNext(sRng)
        Loop While Not sRng Is Nothing And sRng.Address <> fAdd
    End If
 Next J
End Sub

Lưu í nhỏ: Mình việt trên nên E2003
 
Upvote 0
Cảm ơn bạn nhiều,


Code của bạn rất hay. Tuy nhiên, số lượng table của mình rất lớn (khoảng gần 100 bảng và mỗi có có trên 500 dòng), mình dùng code của bạn chạy thử thì kết quả của bảng thứ 6 trở đi lại không chính xác. Bạn có thể giúp mình thêm nữ được không?
Bạn up file bị lỗi tôi mới sửa được
 
Upvote 0
PHP:
Option Explicit
Sub TimNgayThuCap()
 Dim Sh As Worksheet, Rng As Range, sRng As Range
 Dim Col As Integer, J As Integer, Rws As Long
 Dim fAdd As String

 Sheets("Report").Select:           Set Sh = ThisWorkbook.Worksheets("Data")
 Col = Sheets("Report").UsedRange.Columns.Count
 For J = 2 To Col Step 5
    Set Rng = Sh.Range(Sh.Cells(5, J), Sh.Cells(5, J).End(xlDown)).Offset(, 2)
    Rws = Rng.Rows.Count
    Cells(6, J).Resize(Rws).ClearContents
    Set sRng = Rng.Find(Cells(2, J).Value, , xlFormulas, xlWhole)
    If Not sRng Is Nothing Then
        fAdd = sRng.Address
        Do
            Cells(Rws, J).End(xlUp).Offset(1).Value = sRng.Offset(1, -3).Value
            Set sRng = Rng.FindNext(sRng)
        Loop While Not sRng Is Nothing And sRng.Address <> fAdd
    End If
 Next J
End Sub

Lưu í nhỏ: Mình việt trên nên E2003

Không được bạn ạ. Khi mình chạy code thì nó báo lỗi dòng: Cells(6, J).Resize(Rws).ClearContents

Nếu bỏ qua dòng code trên thì chạy lỗi như file đính kèm nhé. Bạn xem lại giúp mình với.

Thanks,
 

File đính kèm

Upvote 0
Không được bạn ạ. Khi mình chạy code thì nó báo lỗi dòng: Cells(6, J).Resize(Rws).ClearContents
Nếu bỏ qua dòng code trên thì chạy lỗi như file đính kèm nhé. Bạn xem lại giúp mình với.

/(/ó báo lỗi trong file bạn mới đưa lên là fải rồi còn gì!
Bạn xem lại thử, các cột , [F],. . . . làm gì có dữ liệu như file mẫu đâu?
Hay là bạn định gài bẫy làm vậy?

Mình thấy bạn có thể viết code, nên đoan chắc bạn dịch được dòng báo lỗi đó chứ, fải không nào?

Khi các cột như vậy không có số liệu, thì trị trong them biến Rws = 65535
(Tiếp nữa bạn tự tìm hiểu đi là vừa!)

Cách khắc fục sẽ như sau:
Thêm trước đó 1 dòng lệnh, rằng
Khi Rws=65535 thì Rws=65500 sẽ là được.


Chúc thành công.
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
/(/ó báo lỗi trong file bạn mới đưa lên là fải rồi còn gì!
Bạn xem lại thử, các cột , [F],. . . . làm gì có dữ liệu như file mẫu đâu?
Hay là bạn định gài bẫy làm vậy?

Mình thấy bạn có thể viết code, nên đoan chắc bạn dịch được dòng báo lỗi đó chứ, fải không nào?

Khi các cột như vậy không có số liệu, thì trị trong them biến Rws = 65535
(Tiếp nữa bạn tự tìm hiểu đi là vừa!)

Cách khắc fục sẽ như sau:
Thêm trước đó 1 dòng lệnh, rằng
Khi Rws=65535 thì Rws=65500 sẽ là được.


Chúc thành công.


Cảm ơn bạn,

Mình cũng mới mày mò và chỉ code được những phương thức đơn giản nên không hiểu lắm về code của mọi người. Cái file mình gửi kèm cho bạn đó là kết quả sau khi mình chạy đoạn code của bạn (Mình có bỏ qua dòng lệnh báo lỗi như trên).

Mình không biết cách fix lỗi đó, nếu thêm điều kiện If như bạn nói thì vị trí đặt End If sẽ nằm đâu nhỉ?
 
Upvote 0
Bạn thêm dòng dưới vào ngay sau lệnh Do đầu tiên
s.Columns(c.Column).Offset(4).Clear

Không được bạn ạ. Nó chỉ chạy được cho 6 Table. Nếu mình tăng thêm số lượng Table lên thì nó cũng chỉ chạy cho Table thứ 6, số còn lại (Từ Table thứ 7 trở đi) thì không trả kết quả.

Bạn fix luôn gúp mình với.


Thanks,
 
Upvote 0
Không được bạn ạ. Nó chỉ chạy được cho 6 Table. Nếu mình tăng thêm số lượng Table lên thì nó cũng chỉ chạy cho Table thứ 6, số còn lại (Từ Table thứ 7 trở đi) thì không trả kết quả.

Bạn fix luôn gúp mình với.


Thanks,

Bạn up file lỗi với nhiều tables thì mới kiểm tra được, còn files bạn gởi có 6 tables thì chạy ổn mà
 
Upvote 0
Mình không biết cách fix lỗi đó, nếu thêm điều kiện If như bạn nói thì vị trí đặt End If sẽ nằm đâu nhỉ?

1 dòng lệnh thôi bạn à, nó nè
Mã:
If Rws>65500 Then Rws= 65500
 
Upvote 0
Bạn up file lỗi với nhiều tables thì mới kiểm tra được, còn files bạn gởi có 6 tables thì chạy ổn mà

File đính kèm bạn nhé.

Mình muốn xin code chạy sao cho không phụ thuộc vào số lượng Table (6 hay 16 hay 90) đều có thể chạy được. Không biết có làm vậy được không nhỉ?

Hiện tại mình đang làm dạng thủ công, nghĩa là tổng cọng có 90 Table, mình dùng For Next để chạy. Tuy nhiên, khi mình thử nghiệm với Khoảng 10 Table thì code chạy khá ổn, nhưng nếu chạy với 90 Table cùng lúc thì dữ liệu lọc ra không chính xác, do vậy, tạm thời mình đang cắt nhỏ ra làm 9 bước, để chạy với 10 Table/1 lượt.

Cách này thủ công và tốn khá nhiều thời gian.

Thêm nữa, hiện Vòng lặp For Next của mình vẫn chưa tối ưu. Do không biết làm cách nào để duyệt từ nhỏ đến lớn, tìm ra giá trị đầu tiên thỏa mãn điều kiện nên mình làm ngược lại: DUYỆT TỪ LỚN ĐẾN NHỎ VÀ TÌM GIÁ TRỊ NHỎ NHẤT. Cách này tốn công và cũng tốn tài nguyên. Nhờ mọi người cho phương án tối ưu nhất.

Code như sau:

--------------------------------------------------------------
Sub Filter1()

Application.ScreenUpdating = False
Dim i, j, k As Integer

S02.Select

For k = 2 To 252 Step 5
Range(Cells(6, k), Cells(35, k)).ClearContents
'Range(Cells(6, k - 1), Cells(35, k - 1)).Sort Cells(6, k - 1), 1
Next k

For k = 2 To 52 Step 5
For j = 6 To 35
For i = 800 To 6 Step -1
If S01.Cells(i, k + 2).Value = S02.Cells(2, k).Value Then
If S01.Cells(i + 1, k + 2).Value = S02.Cells(j, k - 1).Value Then
S02.Cells(j, k).Value = S01.Cells(i + 1, k - 1).Value
'Exit Sub
End If
End If
Next i
Next j
'Range(Cells(6, k - 1), Cells(35, k)).Sort Cells(6, k), 2
Next k

Sheets("Input").Select
[I1].Select
Application.ScreenUpdating = True
End Sub
------------------------------------

Xin cảm ơn,
 

File đính kèm

Upvote 0
[thongbao]Mình muốn xin code chạy sao cho không phụ thuộc vào số lượng Table (6 hay 16 hay 90) đều có thể chạy được. Không biết có làm vậy được không nhỉ?
[/thongbao]

Thì macro ở #8 đã làm được như vậy rồi mà!
 
Upvote 0
Hihi, cao thủ quá
Cái vụ macro mình không rành nhưng bảo dùng công thức nhiều file chạy chậm mình không đồng ý đây nhé! Cụ thể bạn có file nào chạy chậm gửi qua mình, mình xử cho, đảm bảo chạy nhanh ngay!
 
Upvote 0
Ai cũng hiểu, chỉ mình bạn chậm hiểu . . . .

Hihi, cao thủ quá
Cái vụ macro mình không rành nhưng bảo dùng công thức nhiều file chạy chậm mình không đồng ý đây nhé! Cụ thể bạn có file nào chạy chậm gửi qua mình, mình xử cho, đảm bảo chạy nhanh ngay!

Tạm đọc cái này đi, ta bàn tiếp:
http://www.giaiphapexcel.com/forum/...-nhiều-file-chạy-rất-chậm-Ai-biết-xin-chỉ-dẫn
 
Upvote 0

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

Back
Top Bottom