???Code tạo và xóa WB.

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

ThuNghi

Hãy cho rồi sẽ nhận!
Thành viên đã mất
Tham gia
16/8/06
Bài viết
3,808
Được thích
4,449
Mã:
Sub TaoWB()
    Dim wName As String, nName As String, wPath As String
    wName = ThisWorkbook.Name
    wPath = ThisWorkbook.Path
    nName = wPath & "\" & Left(wName, 7) & "-SoChiTiet"
    Workbooks.Add
     ActiveWorkbook.SaveAs Filename:=nName
    ActiveWindow.Close
End Sub
Tôi làm code như trên để tạo 1 WB mới có tên là tên WB hiện hành + "SoChiTiet"
Vấn đề này gặp phải khi tạo sổ cái từ NKC, mỗi sổ mỗi sh. Tôi muốn đưa ra file khác có tên là "KT-07-01-SoChiTiet", KT-07-01 là tên file hiện hành.
1/ Tôi muốn các bạn help làm sao nếu tên "KT-07-01-SoChiTiet" có rồi thì xóa luôn file đó.
2/ Tìm shName theo DMTK, nếu có rồi thì thông qua hay là xóa đi.
Cám ơn nhiều.
 
Tôi chỉnh 1 chút cái code của bạn.

Mã:
Sub TaoWB()
    Dim wName As String, nName As String, wPath As String
    wName = ThisWorkbook.Name
    wPath = ThisWorkbook.Path
    nName = wPath & "\" & Left(wName, 7) & "-SoChiTiet" [B]& ".xls"[/B]
    Workbooks.Add
    [B]Application.DisplayAlerts = False[/B]
    ActiveWorkbook.SaveAs Filename:=nName
    [B]Application.DisplayAlerts = True[/B]
    ActiveWindow.Close
End Sub

Khi tạo 1 workbook (wb) mới mà trùng tên với 1 file đã tạo rồi thì thay vì xoá cái cũ rồi viết lại wb mới thì ta chỉ viết chồng lên nó (overwrite).

Tôi chưa hiểu ý của bạn trong câu số 2 có lẽ vì chữ tắt "DMTK" trong chuyên ngành bạn dùng còn mình thì không biết.

Mến
 
Upvote 0
Cách trên là xoá cái cũ giữ cái mới. Hay là ý bạn là trước khi tạo file mới mà tên file mới trùng với 1 file đã có trong folder (nghĩa là giữ cái cũ xoá cái mới)? Nếu vậy thì cần tạo ra 1 UDF và code được chỉnh thành như sau::

Mã:
Public Function FileExists(FilenameAndPath As String) As Boolean
     FileExists = CBool(Len(Dir(FilenameAndPath)))
End Function

Mã:
Sub TaoWB()
Dim wName As String, nName As String, wPath As String
wName = ThisWorkbook.Name
wPath = ThisWorkbook.Path
nName = wPath & "\" & Left(wName, 7) & "-SoChiTiet" & ".xls"
[B]If FileExists(nName) Then Exit Sub[/B]
Workbooks.Add
ActiveWorkbook.SaveAs Filename:=nName
ActiveWindow.Close
End Sub
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Rất cám ơn Digita, tôi làm theo bạn như sau:
Mã:
Sub TaoWB()
Dim wName As String, nName As String, wPath As String
Dim msgtext, msg_tb As String
With Application
    .ScreenUpdating = False
    .DisplayAlerts = False
End With
wName = ThisWorkbook.Name
wPath = ThisWorkbook.Path
nName = wPath & "\" & Left(wName, 7) & "-SoChiTiet" & ".xls"
If FileExists(nName) Then
     msgtext = "Da ton tai file nay! Ban co muon thay the nay khong!"
     msg_tb = MsgBox(msgtext, vbOKCancel + vbDefaultButton1)
        If msg_tb = vbOK Then
            Workbooks.Add
            ActiveWorkbook.SaveAs Filename:=nName
            ActiveWorkbook.Close
        Else
            Exit Sub
        End If
End If
With Application
    .ScreenUpdating = True
    .DisplayAlerts = True
End With
End Sub
Public Function FileExists(FilenameAndPath As String) As Boolean
     FileExists = CBool(Len(Dir(FilenameAndPath)))
End Function
Bạn xem chỉnh hộ nhé. và phát sinh thêm 1 câu như sau.
Tôi có range("shtk3") (1cột) gồm các tài khỏan mà tôi đã tạo những sh mang tên range("shtk3").cells(i,1), i=1 to range("shtk3").count . Những sh này ở WB tên wName (file gốc)
Tôi muốn move (cắt) tất cả qua WB vừa tạo bên trên. (WB chép chồng lên cái cũ) WB tên nName (file vừa tạo ra)
Bạn giúp hộ nhé.
Cám ơn nhiều.
 
Upvote 0
OK. Trước khi bắt tay vào làm thì cho tôi hỏi lại ý của bạn 1 lần nữa. Trong Workbook (wb) gốc bạn có 1 cột gồm những số tài khoản khác nhau trong cột có tên vùng là shtk3. Bạn muốn khi tạo 1 cái wb mới thì cái workbook mới có các sheet có tên trùng với tất cà các tài khoản trong shtk3. Thí dụ trong vùng shtk3 bạn có 3 tài khoản A, B, C. Wb mới cần có 3 sheet tên là A, B, C.

Có phải là như thế không?
 
Upvote 0
Sao không cho file ví dụ cho dễ học nhỉ.

TC.
 
Upvote 0
rước khi bắt tay vào làm thì cho tôi hỏi lại ý của bạn 1 lần nữa. Trong Workbook (wb) gốc bạn có 1 cột gồm những số tài khoản khác nhau trong cột có tên vùng là shtk3. Bạn muốn khi tạo 1 cái wb mới thì cái workbook mới có các sheet có tên trùng với tất cà các tài khoản trong shtk3. Thí dụ trong vùng shtk3 bạn có 3 tài khoản A, B, C. Wb mới cần có 3 sheet tên là A, B, C.
Đúng là như thế, range("shtk3") như sau: {"a";"b";"c";...} nằm ở WB gốc
Tôi muốn khi tạo WB mới (chi tiết) sẽ có những sh có name là A, B, C...
Tôi đã làm theo kiểu có sh nào mở nWB, move sh đó, save, close. Nhưng nó chạy điên luôn.
Cám ơn nhiều.
 
Upvote 0
Đây là code để tạo 1 workbook (Wb) mới và có những sheet name tương ứng với dữ liệu (DL) trong wb gốc.

Bạn lưu ý những điểm sau đây:

- DL phải ở cột A và bao gồm tên - thí dụ ô A1 có "Tên tài khoản", A2 - AX là các giá trị DL tương ứng với các sheet trong wb mới. Cần chỉnh code nếu bạn thay đổi vị trí DL trong wb gốc.

- Nếu wb mới có trùng tên với cái wb tạo trước thì XL sẽ viết chồng lên cái cũ (tức là overwrite như bạn muốn). Vì vậy phải chèn cái lệnh Application.DisplayAlerts = False để không cho cái dialog box "Do you want to write an existing file?" hiện hình. Không cần xài cái UDF để kiểm tra coi có cái wb cũ nào có trùng tên với cái mới hay không trong trường hợp này.

- Vì không thể có 2 sheet cùng 1 tên nên nếu trong cột A bạn có những DL trùng tên (thí dụ: A, A, A) thì wb mới chỉ cho 1 sheet tên A mà thôi.

- Nếu bạn cần confirm thì chỉ cần bỏ cái applicaiton.displayalerts ra là nó sẽ hỏi bạn có overwrite cái trước không. Nên để code trong workbook before save event để XL tự động "đẻ" ra cái wb mới.với các sheets có tên trong cột A.

Mã:
Sub TaoSheet()
Dim NumEntry As Integer
Dim SourceWb As Workbook
Dim TgtWb As Workbook
Dim NumSht As Integer
Dim iCount As Integer
Dim wPath As String
Mã:
[SIZE=3][FONT=Times New Roman]Set SourceWb = ThisWorkbook
wPath = ThisWorkbook.Path
On Error Resume Next
 
With Range(Cells(1, 1), Cells(Rows.Count, 1).End(xlUp)) 'Du lieu o cot A
.SpecialCells(xlCellTypeBlanks).Delete Shift:=xlUp
.AdvancedFilter Action:=xlFilterInPlace, Unique:=True
End With
 
NumEntry = WorksheetFunction.Subtotal(3, Range(Cells(2, 1), Cells(Rows.Count, 1).End(xlUp)))
Workbooks.Add
Set TgtWb = ThisWorkbook
NumSht = Sheets.Count
 
If NumSht < NumEntry Then
For iCount = NumSht + 1 To NumEntry
    Sheets.Add
    ActiveSheet.Move After:=Sheets(TgtWb.Sheets.Count)
Next
End If
For iCount = 1 To NumEntry
    Sheets(iCount).Name = SourceWb.Sheets(1).Cells(iCount + 1, 1)
Next
nName = wPath & "\" & Left(SourceWb.Name, 7) & "-SoChiTiet" & ".xls"
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:=nName
Application.DisplayAlerts = True
ActiveWindow.Close
ActiveSheet.ShowAllData
End Sub
[/FONT][/SIZE]
Mến
 
Upvote 0
Cám ơn nhiều!
Phần code của Digita chỉ là tạo 1 WB mới có tên là nName và có những sh mang tên theo range. Chắc bạn hiểu sai ý tôi.
Tôi muốn là từ WB gốc, đã có những sh theo range và có DLiệu.
Tạo 1 sub để move tòan bộ những sh thỏa DK (tên sh là từng cell.value trong range) sang 1 WB mới và save là nName.

Nhờ các bạn chỉ hộ cách tạo array từ range
vd: ta có range MyRng có các giá trị: "A", "B", "C"
Làm thế nào chuyển sang array("A", "B", "C") nhằm
sheets(array("A", "B", "C")).select (group các sh)
 
Upvote 0
ThuNghi đã viết:
.....
Nhờ các bạn chỉ hộ cách tạo array từ range
vd: ta có range MyRng có các giá trị: "A", "B", "C"
Làm thế nào chuyển sang array("A", "B", "C") nhằm
sheets(array("A", "B", "C")).select (group các sh)
Bạn tham khảo ví dụ sau:
Mã:
Option Explicit
Public Sub Vidu()
Dim shtName()
Dim shtA, dem
For Each shtA In Worksheets
    dem = dem + 1
    ReDim Preserve shtName(1 To dem)
    shtName(dem) = shtA.Name
Next shtA
Sheets(shtName).Select
End Sub
 
Upvote 0
Lâu lắm mới gặp lại chuyên gia. Code của bạn sao chạy chưa được, có khi tôi sai chỗ nào.
Yêu cầu theo như code group() trong file vidu, nhưng mà tôi không làm được.
Bạn xem file và cụ thể hộ nhé.
Trong file chỉ có 1 range tên là rng có 4 đối tượng.
Cám ơn nhiều lắm!
 

File đính kèm

Upvote 0
Tôi đã chỉnh code để làm cái việc bạn muốn. Trong trường hợp này không cần dùng sheet arrays.

Không ai hiễu rỏ hơn là người trong cuộc. Phải chi bạn đưa ra cái file thí dụ này và mô tả rỏ hơn cái vấn đề bạn cần giải quyết thì bạn đã có câu trả lời chính xác lâu rồi.

Khi đặt câu hỏi bạn nên tránh dùng chữ viết tắt và mô tả chính xác vấn đề để mọi người giúp bạn nhanh chóng bạn nhé.
Mã:
[FONT=Times New Roman][SIZE=3]Public Sub Vidu()[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Dim cel As Variant[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Dim NumEntry As Integer[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Dim SourceWb As Workbook[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Dim TgtWb As Workbook[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Dim NumSht As Integer[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Dim wPath As String[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Dim nName As String[/SIZE][/FONT]
 
[FONT=Times New Roman][SIZE=3]Set SourceWb = ThisWorkbook[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]wPath = ThisWorkbook.Path[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Workbooks.Add[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Set TgtWb = ActiveWorkbook[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]NumSht = Sheets.Count[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]SourceWb.Activate[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]For Each cel In Sheets("DM").Range("A2:A5")[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]SourceWb.Activate[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Sheets(cel.Value).Move After:=TgtWb.Sheets(TgtWb.Sheets.Count)[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Next[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]TgtWb.Activate[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Application.DisplayAlerts = False[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]For cel = 3 To 1 Step -1[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Sheets(cel).Delete[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Next[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Application.DisplayAlerts = True[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]nName = wPath & "\" & Left(SourceWb.Name, 7) & "-SoChiTiet" & ".xls"[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Application.DisplayAlerts = False[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]ActiveWorkbook.SaveAs Filename:=nName[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Application.DisplayAlerts = True[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]ActiveWindow.Close[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]End Sub[/SIZE][/FONT]
 
Upvote 0
Rất cám ơn.
Bạn giúp mình làm thêm theo hướng sheet array nữa nhé.
Câu lệnh ....&"-SoChiTiet" &".xls" có thể bỏ ".xls"
Thỉnh thỏang hơi làm biếng nên có viết tắc, thông cảm nhé.
Nhiều lúc tư duy về đề bài cũng là 1 phương pháp giải.
 
Upvote 0
ThuNghi đã viết:
Rất cám ơn.
Bạn giúp mình làm thêm theo hướng sheet array nữa nhé.
Câu lệnh ....&"-SoChiTiet" &".xls" có thể bỏ ".xls"
Thỉnh thỏang hơi làm biếng nên có viết tắc, thông cảm nhé.
Nhiều lúc tư duy về đề bài cũng là 1 phương pháp giải.
Trời! ThuNghi mà viết đề thi đại học mà dùng các “mật khẩu” thì các em sinh viên vừa đọc vứa …. đoán thì chắc rớt ráo trọi rồi.

Nếu bạn bỏ đoạn ".xls" trong lệnh file saveas thì không sao. XL nó tự động gắn cái tên đuôi vô cho workbook mới.

Theo ý mình thì không nên dùng sheets array trong trường hợp này vì code rất dài. Bạn đã có tên sheet trong cột A rồi tại sao phải gõ lại tên các sheet trong code 1 lần nữa? Và mổi khi bạn có những tên sheet mới thì phải vô code đổi tên sheet rồi code nó mới chạy. Cách đó lượm thượm lắm bạn ơi.

Nếu muốn tìm hiểu thêm về cách sheets array thì code sau đây là 1 thí dụ đơn giản cho mọi người tham khảo. Lưu ý cần có dòng Option Base 1 ở đầu module nếu muốn giá trị nhỏ nhất là 1. không thì giá trị đầu tiên là 0 và XL báo lổi.
Mã:
[FONT=Times New Roman][SIZE=3]Option explicit[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Option Base 1[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Sub ShtArray()[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Dim varWS As Variant, lCnt As Long[/SIZE][/FONT]
 
[SIZE=3][FONT=Times New Roman]   varWS = Array("Sheet1", "Sheet2", "Sheet3")[/FONT][/SIZE]
 
[SIZE=3][FONT=Times New Roman]   For lCnt = LBound(varWS) To UBound(varWS)[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]       MsgBox Sheets(lCnt).Name[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]   Next lCnt[/FONT][/SIZE]
[FONT=Times New Roman][SIZE=3]End Sub[/SIZE][/FONT]

Và sau đây là code Vidu (version 2) được chỉnh sửa đôi chút để chặng các lổi có thể xảy ra khi chạy code nầy.
Mã:
[SIZE=3][FONT=Times New Roman]Public Sub Vidu()
Dim cel As Variant
Dim w As Variant
Dim NumEntry As Integer
Dim SourceWb As Workbook
Dim TgtWb As Workbook
Dim NumSht As Integer
Dim wPath As String
Dim nName As String
Dim MyRange As New Collection
Dim ICount As Variant[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]Set SourceWb = ThisWorkbook
wPath = ThisWorkbook.Path
On Error Resume Next
With Range(Cells(1, 1), Cells(Rows.Count, 1).End(xlUp)) 'Du lieu o cot A
.SpecialCells(xlCellTypeBlanks).Delete Shift:=xlUp
.AdvancedFilter Action:=xlFilterInPlace, Unique:=True
End With
NumEntry = WorksheetFunction.Subtotal(3, Range(Cells(2, 1), Cells(Rows.Count, 1).End(xlUp)))
Range("A1").Select
For ICount = 1 To NumEntry[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]   For Each w In Worksheets
    If ActiveCell(ICount + 1, 1) = w.Name Then
    MyRange.Add ActiveCell(ICount + 1, 1)
    End If
    Next w
Next ICount
ActiveSheet.ShowAllData
Workbooks.Add
Set TgtWb = ActiveWorkbook
NumSht = Sheets.Count
For Each cel In MyRange
SourceWb.Activate
Sheets(cel.Value).Move After:=TgtWb.Sheets(TgtWb.Sheets.Count)
Next
TgtWb.Activate
Application.DisplayAlerts = False
For cel = 3 To 1 Step -1
Sheets(cel).Delete
Next
nName = wPath & "\" & Left(SourceWb.Name, 7) & "-SoChiTiet" & ".xls"
ActiveWorkbook.SaveAs Filename:=nName
Application.DisplayAlerts = True
ActiveWindow.Close
End Sub[/FONT][/SIZE]
Mến
 
Upvote 0
Thấy mà khiếp, cám ơn bạn nhé, mình muốn chuyển tư range -> array cũng có nhiều cái hay lắm, trước mắt có thể thay hàm index trong VBA.
Ta có:
Range("MyRng") gồm có "Mon", "Tue", "Wed", "Thu"
nếu chuyển được sang
MyArray=Array("Mon", "Tue", "Wed", "Thu")
x= MyArray(1) = "Tue"
Có phải thay thế worksheetfunction.index(...) vất vả hơn nhiều.
 
Upvote 0
Web KT

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

Back
Top Bottom