• Hi All

    Please note that at the Chandoo.org Forums there is Zero Tolerance to Spam

    Post Spam and you Will Be Deleted as a User

    Hui...

  • When starting a new post, to receive a quicker and more targeted answer, Please include a sample file in the initial post.

Macro to break data

Hi,

Can anyone help me with code to break data based on values in column E and save it with name in column E. I tried using code in attached file but it is creating files with huge size which is more than size of original file.

Please help
 

Attachments

  • ARM_GL_DETAIL_UPDATED_May'17.xlsm
    25.8 KB · Views: 6
Hi,

Can anyone help me with code to break data based on values in column E and save it with name in column E. I tried using code in attached file but it is creating files with huge size which is more than size of original file.

Please help


Hi Shakti

that is weird. I am not sure what the original macro is doing to inflate the file sizes. Here is another macro that can split files. It sorts the data first and then splits at each change. Try this.

Code:
Sub split_dat2()
    'split data by sorting
    Application.ScreenUpdating = False
   
    Dim cRange As Range, sortCol As Range, firstRow As Range
   
    Set cRange = ActiveCell.CurrentRegion
    Set sortCol = cRange.Columns(5)
    Set sortCol = Range(sortCol.Cells(2), sortCol.Cells(sortCol.Cells.Count() - 1))
    Set firstRow = cRange.Rows(1)
   
    ActiveWorkbook.Worksheets("sheet1").Sort.SortFields.Add Key:=sortCol _
        , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
        xlSortTextAsNumbers
    With ActiveWorkbook.Worksheets("sheet1").Sort
        .SetRange cRange
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
   
    Dim NewWorkbook As Workbook
    Dim ThisWorkbook As Workbook
    Dim NewWorkbookName As String
    Dim relativePath As String
    Dim c As Range, prevC As String, rowNum As Long, i As Long
    Dim lastrow As Integer


    Set ThisWorkbook = ActiveWorkbook
    prevC = ""
    rowNum = 2
   
    For Each c In sortCol
        If c.Value <> prevC Then
            If Not NewWorkbook Is Nothing Then
                NewWorkbook.Close savechanges:=True
            End If
            'we have a new item, time to create a file
            NewWorkbookName = c.Value & ".xlsx"

            Set NewWorkbook = Workbooks.Add
            relativePath = ThisWorkbook.Path & "\split\" & NewWorkbookName
            ActiveWorkbook.SaveAs Filename:=relativePath
            firstRow.Copy Workbooks(NewWorkbookName).Sheets(1).Cells(1, 1)
            i = 2
            prevC = c.Value
        End If
        cRange.Rows(rowNum).Copy Workbooks(NewWorkbookName).Sheets(1).Cells(i, 1)
        i = i + 1
        rowNum = rowNum + 1
    Next c
    NewWorkbook.Close savechanges:=True
    Application.ScreenUpdating = True
End Sub

all the best.
 
I looked at your original workbook. "Something" was lurking in the rows from 82 to 1048576. After highlighting those empty rows / rt click / CLEAR CONTENTS ... then rt click / DELETE ... whatever was there is gone. Ran your macro again and the new split files are reduce to approx. 25 kb each.

Also, I ran the workbook thru a cleaning program which removed alot of unspecified junk as well.
 

Attachments

  • ARM_GL_DETAIL_UPDATED_May'17.xlsm
    29 KB · Views: 5
Hi Shakti

that is weird. I am not sure what the original macro is doing to inflate the file sizes. Here is another macro that can split files. It sorts the data first and then splits at each change. Try this.

Code:
Sub split_dat2()
    'split data by sorting
    Application.ScreenUpdating = False
  
    Dim cRange As Range, sortCol As Range, firstRow As Range
  
    Set cRange = ActiveCell.CurrentRegion
    Set sortCol = cRange.Columns(5)
    Set sortCol = Range(sortCol.Cells(2), sortCol.Cells(sortCol.Cells.Count() - 1))
    Set firstRow = cRange.Rows(1)
  
    ActiveWorkbook.Worksheets("sheet1").Sort.SortFields.Add Key:=sortCol _
        , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
        xlSortTextAsNumbers
    With ActiveWorkbook.Worksheets("sheet1").Sort
        .SetRange cRange
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
  
    Dim NewWorkbook As Workbook
    Dim ThisWorkbook As Workbook
    Dim NewWorkbookName As String
    Dim relativePath As String
    Dim c As Range, prevC As String, rowNum As Long, i As Long
    Dim lastrow As Integer


    Set ThisWorkbook = ActiveWorkbook
    prevC = ""
    rowNum = 2
  
    For Each c In sortCol
        If c.Value <> prevC Then
            If Not NewWorkbook Is Nothing Then
                NewWorkbook.Close savechanges:=True
            End If
            'we have a new item, time to create a file
            NewWorkbookName = c.Value & ".xlsx"

            Set NewWorkbook = Workbooks.Add
            relativePath = ThisWorkbook.Path & "\split\" & NewWorkbookName
            ActiveWorkbook.SaveAs Filename:=relativePath
            firstRow.Copy Workbooks(NewWorkbookName).Sheets(1).Cells(1, 1)
            i = 2
            prevC = c.Value
        End If
        cRange.Rows(rowNum).Copy Workbooks(NewWorkbookName).Sheets(1).Cells(i, 1)
        i = i + 1
        rowNum = rowNum + 1
    Next c
    NewWorkbook.Close savechanges:=True
    Application.ScreenUpdating = True
End Sub

all the best.
HI Thanks for the code

It works super fast.

Is der any way that the splitted files have autofit columns.
 
Hi Shakti
that is weird. I am not sure what the original macro is doing to inflate the file sizes.
I looked at your original workbook. "Something" was lurking in the rows from 82 to 1048576.

That 'something' is formatting… of entire columns. That wouldn't matter but for a full stop (dot) missing in this line:
Code:
.Range("A1:AB" & Range("A1").End(xlDown).Row).Copy Workbooks(NewWorkbookName).Sheets(1).Cells(1, 1)
which should be:
.Range("A1:AB" & .Range("A1").End(xlDown).Row).Copy Workbooks(NewWorkbookName).Sheets(1).Cells(1, 1)

Without it, that range refers to the active sheet which is an empty sheet, so Range("A1").End(xlDown).Row is 1048576. The code does copy that huge range across, because it contains formatting - if there had been no added formatting, it wouldn't have mattered.

There are a couple of other lines with unqualified ranges where it might matter:
lastrow = Columns("E").Cells(Rows.Count).End(xlUp).Row
should be:
lastrow = Sheets(1).Columns("E").Cells(Rows.Count).End(xlUp).Row

lastrow is used later, but in fact isn't necessary at all:
.Range("A1:AB" & lastrow).AutoFilter Field:=5, Criteria1:=c.Value
could be:
.Range("A1").AutoFilter Field:=5, Criteria1:=c.Value

and this one:
For Each c In Sheets(2).Range("A1:A" & Range("A1").End(xlDown).Row).Cells
should be
For Each c In Sheets(2).Range("A1:A" & Sheets(2).Range("A1").End(xlDown).Row).Cells
although you get away with this one since the correct sheet is active when the line is executed!

So all that was/is needed was to add that one dot!
 
I looked at your original workbook. "Something" was lurking in the rows from 82 to 1048576. After highlighting those empty rows / rt click / CLEAR CONTENTS ... then rt click / DELETE ... whatever was there is gone. Ran your macro again and the new split files are reduce to approx. 25 kb each.

Also, I ran the workbook thru a cleaning program which removed alot of unspecified junk as well.
 
p45cal

Thank you for that ! Such a small item with a HUGE difference. Overlooked.
The created files went from 24mb in size to 10kb. Good catch.
 
Back
Top