2017-02-07 50 views
-1

我需要一個宏將我的數據從一個Excel文件拆分爲幾個其他文件。它看起來像這樣:拆分工作簿以使用宏模板分隔文件

 UserList.xls 

User Role Location 
DDAVIS XX  WW 
DDAVIS XS  WW 
GROBERT XW  WP 
SJOBS XX  AA 
SJOBS XS  AA 
SJOBS XW  AA 

我需要的,像這樣的數據複製:

 WW_DDAVIS.xls 

User Role  
DDAVIS XX 
DDAVIS XS 

    WP_GROBERT.xls 
User Role 
GROBERT XW 

    AA_SJOBS.xls 
User Role 
SJOBS XX 
SJOBS XS 
SJOBS XW 

我需要每一個用戶,擁有自己的文件。當我被告知需要使用模板(template.xls)填充文件時,問題就出現了。看起來相同,但源文件中的數據從單元格A2開始,並從單元格A8開始在模板文件中。

要沒有模板複製數據我用這個代碼:

Public Sub SplitToFiles() 

' MACRO SplitToFiles 
' Last update: 2012-03-04 
' Author: mtone 
' Version 1.1 
' Description: 
' Loops through a specified column, and split each distinct values into a separate file by making a copy and deleting rows below and above 
' 
' Note: Values in the column should be unique or sorted. 
' 
' The following cells are ignored when delimiting sections: 
' - blank cells, or containing spaces only 
' - same value repeated 
' - cells containing "total" 
' 
' Files are saved in a "Split" subfolder from the location of the source workbook, and named after the section name. 

Dim osh As Worksheet ' Original sheet 
Dim iRow As Long ' Cursors 
Dim iCol As Long 
Dim iFirstRow As Long ' Constant 
Dim iTotalRows As Long ' Constant 
Dim iStartRow As Long ' Section delimiters 
Dim iStopRow As Long 
Dim sSectionName As String ' Section name (and filename) 
Dim rCell As Range ' current cell 
Dim owb As Workbook ' Original workbook 
Dim sFilePath As String ' Constant 
Dim iCount As Integer ' # of documents created 

iCol = Application.InputBox("Enter the column number used for splitting", "Select column", 2, , , , , 1) 
iRow = Application.InputBox("Enter the starting row number (to skip header)", "Select row", 5, , , , , 1) 
iFirstRow = iRow 

Set osh = Application.ActiveSheet 
Set owb = Application.ActiveWorkbook 
iTotalRows = osh.UsedRange.Rows.Count 
sFilePath = Application.ActiveWorkbook.Path 

If Dir(sFilePath + "\Split", vbDirectory) = "" Then 
    MkDir sFilePath + "\Split" 
End If 

'Turn Off Screen Updating Events 
Application.EnableEvents = False 
Application.ScreenUpdating = False 

Do 
    ' Get cell at cursor 
    Set rCell = osh.Cells(iRow, iCol) 
    sCell = Replace(rCell.Text, " ", "") 

    If sCell = "" Or (rCell.Text = sSectionName And iStartRow <> 0) Or InStr(1, rCell.Text, "total", vbTextCompare) <> 0 Then 
     ' Skip condition met 
    Else 
     ' Found new section 
     If iStartRow = 0 Then 
      ' StartRow delimiter not set, meaning beginning a new section 
      sSectionName = rCell.Text 
      iStartRow = iRow 
     Else 
      ' StartRow delimiter set, meaning we reached the end of a section 
      iStopRow = iRow - 1 

      ' Pass variables to a separate sub to create and save the new worksheet 
      CopySheet osh, iFirstRow, iStartRow, iStopRow, iTotalRows, sFilePath, sSectionName, owb.fileFormat 
      iCount = iCount + 1 

      ' Reset section delimiters 
      iStartRow = 0 
      iStopRow = 0 

      ' Ready to continue loop 
      iRow = iRow - 1 
     End If 
    End If 

    ' Continue until last row is reached 
    If iRow < iTotalRows Then 
      iRow = iRow + 1 
    Else 
     ' Finished. Save the last section 
     iStopRow = iRow 
     CopySheet osh, iFirstRow, iStartRow, iStopRow, iTotalRows, sFilePath, sSectionName, owb.fileFormat 
     iCount = iCount + 1 

     ' Exit 
     Exit Do 
    End If 
Loop 

'Turn On Screen Updating Events 
Application.ScreenUpdating = True 
Application.EnableEvents = True 

MsgBox Str(iCount) + " documents saved in " + sFilePath 


End Sub 

Public Sub DeleteRows(targetSheet As Worksheet, RowFrom As Long, RowTo As Long) 

Dim rngRange As Range 
Set rngRange = Range(targetSheet.Cells(RowFrom, 1), targetSheet.Cells(RowTo, 1)).EntireRow 
rngRange.Select 
rngRange.Delete 

End Sub 


Public Sub CopySheet(osh As Worksheet, iFirstRow As Long, iStartRow As Long, iStopRow As Long, iTotalRows As Long, sFilePath As String, sSectionName As String, fileFormat As XlFileFormat) 
    Dim ash As Worksheet ' Copied sheet 
    Dim awb As Workbook ' New workbook 

    ' Copy book 
    osh.Copy 
    Set ash = Application.ActiveSheet 

    ' Delete Rows after section 
    If iTotalRows > iStopRow Then 
     DeleteRows ash, iStopRow + 1, iTotalRows 
    End If 

    ' Delete Rows before section 
    If iStartRow > iFirstRow Then 
     DeleteRows ash, iFirstRow, iStartRow - 1 
    End If 

    ' Select left-topmost cell 
    ash.Cells(1, 1).Select 

    ' Clean up a few characters to prevent invalid filename 
    sSectionName = Replace(sSectionName, "/", " ") 
    sSectionName = Replace(sSectionName, "\", " ") 
    sSectionName = Replace(sSectionName, ":", " ") 
    sSectionName = Replace(sSectionName, "=", " ") 
    sSectionName = Replace(sSectionName, "*", " ") 
    sSectionName = Replace(sSectionName, ".", " ") 
    sSectionName = Replace(sSectionName, "?", " ") 

    ' Save in same format as original workbook 
    ash.SaveAs sFilePath + "\Split\" + sSectionName, fileFormat 

    ' Close 
    Set awb = ash.Parent 
    awb.Close SaveChanges:=False 
End Sub 

在這一個問題是,我不知道如何讓名不DDAVIS.xls,但使用WW_DDAVIS.xls(location_user。 XLS)。第二個問題 - 使用模板。該代碼只是複製整個工作簿並擦除所有錯誤的數據。我需要的只是將正確數據的值複製到此模板中。

不幸的是我沒有找到工作代碼,我在VBA中並不那麼流利。

我嘗試了另外一種,只有一半。它將模板複製到每個文件並正確命名,但我無法弄清楚如何將單元複製到正確的文件。

Option Explicit 

Sub copyTemplate() 
    Dim lRow, x As Integer 
    Dim wbName As String 
    Dim fso  As Variant 
    Dim dic  As Variant 
    Dim colA  As String 
    Dim colB  As String 
    Dim colSep  As String 
    Dim copyFile As String 
    Dim copyTo  As String 

    Set dic = CreateObject("Scripting.Dictionary") 'dictionary to ensure that duplicates are not created 
    Set fso = CreateObject("Scripting.FileSystemObject") 'file scripting object for fiile system manipulation 

    colSep = "_" 'separater between values of col A and col B for file name 
    dic.Add colSep, vbNullString ' ensuring that we never create a file when both columns are blank in between 

    'get last used row in col A 
    lRow = Range("A" & Rows.Count).End(xlUp).Row 

    x = 1 
    copyFile = "c:\location\Template.xls" 'template file to copy 
    copyTo = "C:\location\List\" 'location where copied files need to be copied 

    Do 
    x = x + 1 

    colA = Range("G" & x).Value 'col a value 

    colB = Range("A" & x).Value ' col b value 

    wbName = colA & colSep & colB ' create new file name 

    If (Not dic.Exists(wbName)) Then 'ensure that we have not created this file name before 
     fso.copyFile copyFile, copyTo & wbName & ".xls" 'copy the file 
     dic.Add wbName, vbNullString 'add to dictionary that we have created this file 
    End If 

Loop Until x = lRow 

Set dic = Nothing ' clean up 
Set fso = Nothing ' clean up 

End Sub 

回答

0
sub test() 
dim wb 
dim temp 
dim rloc 
rloc= "result files location" 
set wb =thisworkbook 
set temp= workbook.open(template path) 
' getting last row 
lrow=wb.sheets(1).range("A1:A"&rows.count).end(xlup).row 
icounter=0 
for i=2 to lrow 'leaving out the header row 
with wb.sheets(1) 
if cells(i,1).value=cells(i,1).offset(1,1).value then 
icounter=icounter+1 
else 
if icounter>0 then 
range(cells(i,1):(cells(i,1).offset(-icounter,2)).copy 
wb.sheet(8,1).pastespecial xlvalues 
application.cutcopymode=false 
filename=str(cells(i,1).value) & "_" & str(cells(i,3).value) & "".xls" 
chdir rloc 
temp.saveas(filename,xlworkbookdefault) 
else 
range(cells(i,1):cells(i,2)).copy 
wb.sheets(8,1).pastespecial xlvalues 
application.cutcopymode=false 
filename=str(cells(i,1).value) & "_" & str(cells(i,3).value) & ".xls" 
chdir rloc 
temp.saveas(filename,xlworkbookdefault) 
end if 
end if 
end with 
next i 
wb.close savechanges:=false 
temp.close savechanges:=false 
end sub 

這可能工作。我沒有測試代碼。它有點粗俗。我也只是vba的初學者。如果它包含錯誤,請原諒我。 看看邏輯。如果你想從頭開始創建一個代碼。

0

@Sivaprasath V 謝謝,看起來應該工作。我已經改變了一點,看起來更好,並修復了一些問題

Sub test() 
Dim wb 
Dim temp 
Dim rloc 

rloc = "C:\LOCATION\result\" 

Set wb = ThisWorkbook 
Set temp = Workbooks.Open("C:\LOCATION\Template.xls") 
' getting last row 
lRow = wb.Sheets(1).Range("A1:A" & Rows.Count).End(xlDown).Row 'changed xlUp for xlDown 
icounter = 0  

For i = 2 To lRow 'leaving out the header row 

With wb.Sheets(1) 
     Range("C2").Value = Cells(i, 1).Value 
    If Cells(i, 1).Value = Cells(i, 1).Offset(1, 0).Value Then 'changed offset from (1,1) 
     icounter = icounter + 1 

    Else 
     If icounter > 0 Then 
      Range(cells(i,1):(cells(i,1).offset(-icounter,7)).Copy 'error 
      wb.Sheet(8, 1).PasteSpecial xlValues 
      Application.CutCopyMode = False 
      Filename = Str(Cells(i, 1).Value) & "_" & Str(Cells(i, 3).Value) & ".xls" 
      ChDir rloc 
      temp.SaveAs Filename, xlWorkbookDefault 
     Else 
      Range(cells(i,1):cells(i,7)).Copy       'error 
      wb.Sheets(8, 1).PasteSpecial xlValues 
      Application.CutCopyMode = False 
      Filename = Str(Cells(i, 1).Value) & "_" & Str(Cells(i, 3).Value) & ".xls" 
      ChDir rloc 
      temp.SaveAs Filename, xlWorkbookDefault 
     End If 
    End If 
End With 
Next i 
wb.Close savechanges:=False 
temp.Close savechanges:=False 
End Sub 

我與一個錯誤,我不明白的戰鬥。在行:

Range(cells(i,1):(cells(i,1).offset(-icounter,7)).Copy 

這:

Range(cells(i,1):cells(i,7)).Copy 

有一個錯誤說:

Compile error: 

Expected: list separator or) 

無法弄清楚如何解決它。代碼對我來說很好。

@EDIT

繞到錯誤使用新的變量( 「C」 &我& 「:」 & 「F」 &我 - icounter) 它的工作的一些細微的變化後,感謝:)