Hoàng Nhật Phương
Thành viên gắn bó



- Tham gia
- 5/11/15
- Bài viết
- 1,895
- Được thích
- 1,219
(1) Folder được chỉ định đường dẫn hay theo lựa chọn của người dùng?1.Lấy phần ngày tháng năm của tên foder đưa vào ô A3 như dữ liệu mẫu:
2. Xóa toàn bộ các dòng có dữ liệu tại Cot4(cộtE) vùng màu vàng trong cot4 khi trùng tháng và năm với ô A3 hoặc tên thư mục
(1) Folder được chỉ định đường dẫn hay theo lựa chọn của người dùng?
Ngày/tháng/năm trong tên folder đó được viết (format) như nào?
(Dấu hiệu nhận biết là ngày tháng năm?)
(2) Xóa dòng ở đây được hiểu như nào?
row().delete hay clear contents
Chào befaint, cảm ơn bạn nhiều đã quan tâm đến bài viết này:
1. Folder "Thang 01-2017" để không có qui định .../Thang 01-2017
Ngày/tháng/năm của tên folder có 7 ký tự cuối: "01-2017" là tháng-năm
2. Xóa dòng theo kiểu chỉ xóa dữ liệu (lear contents) bạn ạ.
Rất mong bạn và mọi người xem giúp.
Sub Main()
Dim nFoLder As String, d As Variant, tmp As Variant, z As Long, dd As Variant, r As Long, m As Long
nFoLder = GetFolder("")
If nFoLder = "" Then Exit Sub
Sheet1.Range("A3") = Right(Mid(nFoLder, InStrRev(nFoLder, "\") + 1), 7)
d = Sheet1.Range("A3")
If TypeName(d) = "Date" Then
m = WorksheetFunction.EoMonth(d, 0)
d = CLng(d)
With Sheet1
z = .Range("E" & .Rows.Count).End(xlUp).Row
If z < 5 Then Exit Sub
tmp = .Range("E5:E" & z).Value2
For r = 1 To UBound(tmp, 1)
dd = tmp(r, 1)
If IsNumeric(dd) Then
dd = CLng(dd)
If dd >= d And dd <= m Then
.Rows(r + 4).ClearContents
End If
End If
Next r
End With
End If
End Sub
'-------------------------------------------------
Function GetFolder(strPath As String) As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem
Set fldr = Nothing
End Function
Mã:Sub Main() Dim nFoLder As String, d As Variant, tmp As Variant, z As Long, dd As Variant, r As Long, m As Long nFoLder = GetFolder("") If nFoLder = "" Then Exit Sub Sheet1.Range("A3") = Right(Mid(nFoLder, InStrRev(nFoLder, "\") + 1), 7) d = Sheet1.Range("A3") If TypeName(d) = "Date" Then m = WorksheetFunction.EoMonth(d, 0) d = CLng(d) With Sheet1 z = .Range("E" & .Rows.Count).End(xlUp).Row If z < 5 Then Exit Sub tmp = .Range("E5:E" & z).Value2 For r = 1 To UBound(tmp, 1) dd = tmp(r, 1) If IsNumeric(dd) Then dd = CLng(dd) If dd >= d And dd <= m Then .Rows(r + 4).ClearContents End If End If Next r End With End If End Sub '------------------------------------------------- Function GetFolder(strPath As String) As String Dim fldr As FileDialog Dim sItem As String Set fldr = Application.FileDialog(msoFileDialogFolderPicker) With fldr .Title = "Select a Folder" .AllowMultiSelect = False .InitialFileName = strPath If .Show <> -1 Then GoTo NextCode sItem = .SelectedItems(1) End With NextCode: GetFolder = sItem Set fldr = Nothing End Function
Bạn cho thêm có thể bỏ phần tìm tìm kiếm lựa chọn thư mục không ạ.
Vì file chạy của Oanh Thơ muốn lấy trực tiếp tên của thư mục chứa nó phần màu đỏ (.../Thang 01-2017/Xoatheothang.xlsm) đỡ mất công tìm kiếm lựa chọn đường dẫn bạn ạ.
Muốn lấy folder chứa chính file excel đang xử lý?(1) Folder được chỉ định đường dẫn hay theo lựa chọn của người dùng?
Mục đích của bài toán này là:
Hàng ngày Oanh Thơ muốn update dữ liệu trong tháng và sau mỗi lần update phải xóa hết dữ liệu từ đầu tháng đến giờ để update lại từ đầu tháng đến ngày mới nhất.
nhưng vì trong bảng dữ liệu còn rất nhiều các dữ liệu không cùng tháng vì vậy cần phải lựa chọn theo tháng để xóa.
Function GetFolder()
'Và
nFoLder = GetFolder("")
If nFoLder = "" Then Exit Sub
Sheet1.Range("A3") = Right(Mid(nFoLder, InStrRev(nFoLder, "\") + 1), 7)
Nếu vậy thì nhập luôn ngày đầu tiên của tháng đó vào [A3] cho rồi...
[A3]=01/01/2017 (format là date)
rồi xóa:
Mã:Function GetFolder() 'Và nFoLder = GetFolder("") If nFoLder = "" Then Exit Sub Sheet1.Range("A3") = Right(Mid(nFoLder, InStrRev(nFoLder, "\") + 1), 7)
Xin chào befaint
Cảm ơn bạn đã thông tin lại ạ.
Mới đầu Oanh Thơ cũng có ý định nhập luôn vào ô A3 rồi a, nhưng nghĩ có thể dùng code để tránh trường hợp nhầm lẫn hoặc quên lên nhân tiện hỏi luôn mục này bạn ạ.![]()
Sub Main()
Dim nFoLder As String, d As Variant, tmp As Variant, z As Long, dd As Variant, r As Long, m As Long
nFoLder = ThisWorkbook.Path
Sheet1.Range("A3") = Right(Mid(nFoLder, InStrRev(nFoLder, "\") + 1), 7)
d = Sheet1.Range("A3")
If TypeName(d) = "Date" Then
m = WorksheetFunction.EoMonth(d, 0)
d = CLng(d)
With Sheet1
z = .Range("E" & .Rows.Count).End(xlUp).Row
If z < 5 Then Exit Sub
tmp = .Range("E5:E" & z).Value2
For r = 1 To UBound(tmp, 1)
dd = tmp(r, 1)
If IsNumeric(dd) Then
dd = CLng(dd)
If dd >= d And dd <= m Then
.Rows(r + 4).ClearContents
End If
End If
Next r
End With
End If
End Sub
Thay cả bài #4 bằng đoạn sau:
Mã:Sub Main() Dim nFoLder As String, d As Variant, tmp As Variant, z As Long, dd As Variant, r As Long, m As Long nFoLder = ThisWorkbook.Path Sheet1.Range("A3") = Right(Mid(nFoLder, InStrRev(nFoLder, "\") + 1), 7) d = Sheet1.Range("A3") If TypeName(d) = "Date" Then m = WorksheetFunction.EoMonth(d, 0) d = CLng(d) With Sheet1 z = .Range("E" & .Rows.Count).End(xlUp).Row If z < 5 Then Exit Sub tmp = .Range("E5:E" & z).Value2 For r = 1 To UBound(tmp, 1) dd = tmp(r, 1) If IsNumeric(dd) Then dd = CLng(dd) If dd >= d And dd <= m Then .Rows(r + 4).ClearContents End If End If Next r End With End If End Sub
Xin chào befaint,
Code trên OK rồi, cảm ơn bạn nhiều.
Nhân chủ đề này bạn và mọi người cho oanh thơ hỏi thêm:
Oanh Thơ muốn xóa đi toàn bộ dữ liệu 6 tháng trở về trước dựa theo ngày tháng tại ô A3 thì code sẽ như thế nào ạ.
Ví dụ:
[A3]=01/01/2017 (format là date) thì dữ liệu cần xóa là: =EOMONTH(A3,-6) => từ ngày 31/07/2016 trở về trước.
Sub Main()
Application.ScreenUpdating = False
Dim nFoLder As String, d As Variant, tmp As Variant, z As Long, dd As Variant, r As Long, m As Long
nFoLder = ThisWorkbook.Path
Sheet1.Range("A3") = Right(Mid(nFoLder, InStrRev(nFoLder, "\") + 1), 7)
d = Sheet1.Range("A3")
If TypeName(d) = "Date" Then
m = WorksheetFunction.EoMonth(d, -6) 'Mốc thời gian thứ nhất = m
d = CLng(d) 'Mốc thời gian thức hai = d
With Sheet1
z = .Range("E" & .Rows.Count).End(xlUp).Row
If z < 5 Then Exit Sub
tmp = .Range("E5:E" & z).Value2
For r = 1 To UBound(tmp, 1)
dd = tmp(r, 1)
If IsNumeric(dd) Then
dd = CLng(dd) 'Thời gian cần đối chiếu = dd
If dd > m And dd < d Then 'Nếu dd nằm trong khoảng thời gian từ min(m,d)=m tới max(m,d)=d thì:
.Rows(r + 4).ClearContents
End If
End If
Next r
End With
End If
Application.ScreenUpdating = True
End Sub
(1) "Nhân chủ đề này bạn và mọi người cho oanh thơ hỏi thêm:" = "Ah, mà cho hỏi thêm nếu..."
Cần hỏi thêm gì thì cứ hỏi, không cần "hoa mỹ". Không phải ai cũng thích điều đó.
(2)
Mã:Sub Main() Application.ScreenUpdating = False Dim nFoLder As String, d As Variant, tmp As Variant, z As Long, dd As Variant, r As Long, m As Long nFoLder = ThisWorkbook.Path Sheet1.Range("A3") = Right(Mid(nFoLder, InStrRev(nFoLder, "\") + 1), 7) d = Sheet1.Range("A3") If TypeName(d) = "Date" Then m = WorksheetFunction.EoMonth(d, -6) 'Mốc thời gian thứ nhất = m d = CLng(d) 'Mốc thời gian thức hai = d With Sheet1 z = .Range("E" & .Rows.Count).End(xlUp).Row If z < 5 Then Exit Sub tmp = .Range("E5:E" & z).Value2 For r = 1 To UBound(tmp, 1) dd = tmp(r, 1) If IsNumeric(dd) Then dd = CLng(dd) 'Thời gian cần đối chiếu = dd If dd > m And dd < d Then 'Nếu dd nằm trong khoảng thời gian từ min(m,d)=m tới max(m,d)=d thì: .Rows(r + 4).ClearContents End If End If Next r End With End If Application.ScreenUpdating = True End Sub
Xin chào các bạn,
Các bạn giúp tôi 1 đoạn code: xóa các dòng dữ liệu tính từ 1 thời điểm cho sẵn trở về trước theo file đính kèm này với ạ.
Sub Main()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim d As Variant, tmp As Variant, z As Long, dd As Variant, r As Long
d = Sheet2.Range("D2")
If TypeName(d) = "Date" Then
d = CLng(d)
With Sheet1
z = .Range("M" & .Rows.Count).End(xlUp).Row
If z < 5 Then Exit Sub
tmp = .Range("M5:M" & z).Value2: z = UBound(tmp, 1)
For r = z To 1 Step -1
dd = tmp(r, 1)
If IsNumeric(dd) Then
dd = CLng(dd)
If dd < d Then
.Rows(r + 4).Delete
End If
End If
Next r
End With
End If
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
(1) Code: Siêu chậm
Mã:Sub Main() Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Dim d As Variant, tmp As Variant, z As Long, dd As Variant, r As Long d = Sheet2.Range("D2") If TypeName(d) = "Date" Then d = CLng(d) With Sheet1 z = .Range("M" & .Rows.Count).End(xlUp).Row If z < 5 Then Exit Sub tmp = .Range("M5:M" & z).Value2: z = UBound(tmp, 1) For r = z To 1 Step -1 dd = tmp(r, 1) If IsNumeric(dd) Then dd = CLng(dd) If dd < d Then .Rows(r + 4).Delete End If End If Next r End With End If Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub
(2) Thao tác: Siêu nhanh
- Tại sheet1, Date filters cột M, điều kiện: Before 01/09/2016. OK
- Chọn vùng dữ liệu vừa lọc được (chọn cả row), nhấn alt ; nhấn tiếp ctrl -
- Hủy lọc. Kết thúc.
Cảm ơn befaint
1.Đúng là siêu chậm (T_T), hic chạy mãi không thấy kết quả,thảo nào khi chạy các code trên cũng chậm như vậy.
có cách nào khác để giải quyết nhanh bằng code không bạn.
Sub Mainn()
Application.ScreenUpdating = False
Dim d As Variant, tmp As Variant, z As Long, dd As Variant, r As Long
Dim KQ() As Variant, c As Long, k As Long, j As Long
d = Sheet2.Range("D2")
If TypeName(d) = "Date" Then
d = CLng(d)
With Sheet1
z = .Range("M" & .Rows.Count).End(xlUp).Row
If z < 5 Then Exit Sub
tmp = .Range("B5:BI" & z).Value2: z = UBound(tmp, 1): c = UBound(tmp, 2)
ReDim KQ(1 To z, 1 To c)
For r = 1 To z
dd = tmp(r, 12)
If IsNumeric(dd) Then
dd = CLng(dd)
If dd >= d Then
j = j + 1
For k = 1 To c
KQ(j, k) = tmp(r, k)
Next k
End If
End If
Next r
If j Then
.Range("B5").Resize(z, c).ClearContents
.Range("B5").Resize(j, c) = KQ
End If
End With
End If
Application.ScreenUpdating = True
End Sub
Code nhanh đây (bài trước thì yêu cầu xóa dữ liệu, bài này lại cần xóa dòng...)
Mã:Sub Mainn() Application.ScreenUpdating = False Dim d As Variant, tmp As Variant, z As Long, dd As Variant, r As Long Dim KQ() As Variant, c As Long, k As Long, j As Long d = Sheet2.Range("D2") If TypeName(d) = "Date" Then d = CLng(d) With Sheet1 z = .Range("M" & .Rows.Count).End(xlUp).Row If z < 5 Then Exit Sub tmp = .Range("B5:BI" & z).Value2: z = UBound(tmp, 1): c = UBound(tmp, 2) ReDim KQ(1 To z, 1 To c) For r = 1 To z dd = tmp(r, 12) If IsNumeric(dd) Then dd = CLng(dd) If dd >= d Then j = j + 1 For k = 1 To c KQ(j, k) = tmp(r, k) Next k End If End If Next r If j Then .Range("B5").Resize(z, c).ClearContents .Range("B5").Resize(j, c) = KQ End If End With End If Application.ScreenUpdating = True End Sub
Sub DeleteRows()
Dim DK, tmp, Drng As Range, Rng As Range, i As Long
DK = Sheet2.Range("D2").Value
If Not TypeName(DK) = "Date" Then Exit Sub
DK = CLng(DK)
i = Sheet1.Range("M" & Sheet1.Rows.Count).End(xlUp).Row
If i < 5 Then Exit Sub
Set Drng = Sheet1.Range("M5:M" & i)
For i = 1 To Drng.Rows.Count
tmp = Drng(i, 1).Value
If TypeName(tmp) = "Date" Then
If CLng(tmp) < DK Then
If Rng Is Nothing Then
Set Rng = Drng(i, 1)
Else
Set Rng = Union(Rng, Drng(i, 1))
End If
End If
End If
Next i
If Not Rng Is Nothing Then Rng.EntireRow.Delete
End Sub
nếu bạn còn thích và vẫn thích xóa dòngMã:Sub DeleteRows() Dim DK, tmp, Drng As Range, Rng As Range, i As Long DK = Sheet2.Range("D2").Value If Not TypeName(DK) = "Date" Then Exit Sub DK = CLng(DK) i = Sheet1.Range("M" & Sheet1.Rows.Count).End(xlUp).Row If i < 5 Then Exit Sub Set Drng = Sheet1.Range("M5:M" & i) For i = 1 To Drng.Rows.Count tmp = Drng(i, 1).Value If TypeName(tmp) = "Date" Then If CLng(tmp) < DK Then If Rng Is Nothing Then Set Rng = Drng(i, 1) Else Set Rng = Union(Rng, Drng(i, 1)) End If End If End If Next i If Not Rng Is Nothing Then Rng.EntireRow.Delete End Sub