Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Too many characters in Excel cell won't copy over

Status
Not open for further replies.

rabley

Programmer
Jul 9, 2007
25
US
I need to include a macro in my spreadsheet that will take a directory of files and combine them into a single specific sheet in my spreadsheet. I found code here( that I could tweak for my specific purposes, and it works in most cases. After a few test runs, I'm now guessing that it's only when a cell has too long of a string that the macro throws an error and comes to a halt. A cell with 863 characters is fine, but a cell with 1,042 characters will stop the macro. Can anyone help me? Since I didn't write the original code, I don't feel I understand it enough to track down the problem. (I'm sorry this code is so long - 90% of the responses I see on this forum ask the OP to post more of his/her code, so I'm trying to think ahead)

Code:
Sub Get_Data(FileNameInA As Boolean, PasteAsValues As Boolean, SourceShName As String, _
             SourceShIndex As Integer, SourceRng As String, StartCell As String)
             
    On Error GoTo A_Error:
                
    Dim SourceRcount As Long
    Dim SourceRange As Range, destrange As Range
    Dim mybook As Workbook, BaseWks As Worksheet
    Dim rnum As Long, CalcMode As Long
    Dim SourceSh As Variant
    Dim sh As Worksheet

    'Change ScreenUpdating, Calculation and EnableEvents
    With Application
        CalcMode = .Calculation
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .EnableEvents = False
    End With

    'Add a new workbook with one sheet named "Combined Sheet"
    Set BaseWks = ThisWorkbook.Worksheets.Add
    BaseWks.Name = "Combined Sheet"

    'Set start row for the Data
    rnum = 1

    'Check if we use a named sheet or the index
    If SourceShName = "" Then
        SourceSh = SourceShIndex
    Else
        SourceSh = SourceShName
    End If

    'Loop through all files in the array(myFiles)
    If fnum > 0 Then
        For fnum = LBound(MyFiles) To UBound(MyFiles)
            Set mybook = Nothing
            On Error Resume Next
            Set mybook = Workbooks.Open(MyFiles(fnum))
            On Error GoTo 0

            If Not mybook Is Nothing Then

                If LCase(SourceShName) <> "all" Then

                    'Set SourceRange and check if it is a valid range
                    On Error Resume Next

                    If StartCell <> "" Then
                        With mybook.Sheets(SourceSh)
                            Set SourceRange = .Range(StartCell & ":" & RDB_Last(3, .Cells))
                        End With
                    Else
                        With mybook.Sheets(SourceSh)
                            Set SourceRange = Application.Intersect(.UsedRange, .Range(SourceRng))
                        End With
                    End If

                    If Err.Number > 0 Then
                        Err.Clear
                        Set SourceRange = Nothing
                    Else
                        'if SourceRange use all columns then skip this file
                        If SourceRange.Columns.Count >= BaseWks.Columns.Count Then
                            Set SourceRange = Nothing
                        End If
                    End If
                    On Error GoTo 0

                    If Not SourceRange Is Nothing Then

                        'Check if there enough rows to paste the data
                        SourceRcount = SourceRange.Rows.Count
                        If rnum + SourceRcount >= BaseWks.Rows.Count Then
                            MsgBox "Sorry there are not enough rows in the sheet to paste"
                            mybook.Close savechanges:=False
                            BaseWks.Parent.Close savechanges:=False
                            GoTo ExitTheSub
                        End If

                        'Set the destination cell
                        If FileNameInA = True Then
                            Set destrange = BaseWks.Range("B" & rnum)
                            With SourceRange
                                BaseWks.Cells(rnum, "A"). _
                                        Resize(.Rows.Count).Value = MyFiles(fnum)
                            End With
                        Else
                            Set destrange = BaseWks.Range("A" & rnum)
                        End If
'
                        'Copy/paste the data
                        If PasteAsValues = True Then
                            With SourceRange
                                Set destrange = destrange. _
                                                Resize(.Rows.Count, .Columns.Count)
                            End With
                            destrange.NumberFormat = "@"
                            destrange.Value = SourceRange.Value
                        Else
                            SourceRange.Copy destrange
                        End If

                        rnum = rnum + SourceRcount
                    End If

                    'Close the workbook without saving
                    On Error Resume Next
                    Application.DisplayAlerts = False
                    mybook.Close savechanges:=False
                    Application.DisplayAlerts = True
                    On Error GoTo 0

                Else

                    'Loop through all sheets in mybook
                    For Each sh In mybook.Worksheets

                        'Set SourceRange and check if it is a valid range
                        On Error Resume Next

                        If StartCell <> "" Then
                            With sh
                                Set SourceRange = .Range(StartCell & ":" & RDB_Last(3, .Cells))
                            End With
                        Else
                            With sh
                                Set SourceRange = Application.Intersect(.UsedRange, .Range(SourceRng))
                            End With
                        End If

                        If Err.Number > 0 Then
                            Err.Clear
                            Set SourceRange = Nothing
                        Else
                            'if SourceRange use all columns then skip this file
                            If SourceRange.Columns.Count >= BaseWks.Columns.Count Then
                                Set SourceRange = Nothing
                            End If
                        End If
                        On Error GoTo 0

                        If Not SourceRange Is Nothing Then

                            'Check if there are enough rows to paste the data
                            SourceRcount = SourceRange.Rows.Count
                            If rnum + SourceRcount >= BaseWks.Rows.Count Then
                                MsgBox "Sorry, there are not enough rows in the sheet to paste"
                                mybook.Close savechanges:=False
                                BaseWks.Parent.Close savechanges:=False
                                GoTo ExitTheSub
                            End If

                            'Set the destination cell
                            If FileNameInA = True Then
                                Set destrange = BaseWks.Range("B" & rnum)
                                With SourceRange
                                    BaseWks.Cells(rnum, "A"). _
                                            Resize(.Rows.Count).Value = MyFiles(fnum)
                                End With
                            Else
                                Set destrange = BaseWks.Range("A" & rnum)
                            End If

                            'Copy/paste the data
                            If PasteAsValues = True Then
                                With SourceRange
                                    Set destrange = destrange. _
                                                    Resize(.Rows.Count, .Columns.Count)
                                End With
                                destrange.Value = SourceRange.Value
                            Else
                                SourceRange.Copy destrange
                            End If

                            rnum = rnum + SourceRcount
                        End If

                    Next sh

                    'Close the workbook without saving
                    mybook.Close savechanges:=False
                End If
            End If
        Next fnum

    End If

ExitTheSub:
    'Restore ScreenUpdating, Calculation and EnableEvents
    With Application
        .ScreenUpdating = True
        .EnableEvents = True
        .Calculation = CalcMode
    End With
    Erase MyFiles()
    
A_Error:
    If Err.Number <> 0 Then
        MsgBox "Get_Data procedure; Error number: " & Err.Number & " , Description: " & Err.Description
   End If
End Sub
 
What error are you getting? On what line of code does it return the error?

For what it's worth, I use the following code to combine all worksheets in a given folder. This assumes that all workbooks contain one worksheet and they all have the same columns. I just tested it with a cell that contains over 2000 characters and it ran fine.

Code:
Private Const BIF_RETURNONLYFSDIRS As Long = &H1
Private Const BIF_DONTGOBELOWDOMAIN As Long = &H2
Private Const BIF_RETURNFSANCESTORS As Long = &H8
Private Const BIF_BROWSEFORCOMPUTER As Long = &H1000
Private Const BIF_BROWSEFORPRINTER As Long = &H2000
Private Const BIF_BROWSEINCLUDEFILES As Long = &H4000
Private Const MAX_PATH As Long = 260

Function BrowseFolder(Optional Caption As String, _
    Optional InitialFolder As String) As String

    Dim SH As Shell32.Shell
    Dim F As Shell32.Folder

    Set SH = New Shell32.Shell
    Set F = SH.BrowseForFolder(0&, Caption, BIF_RETURNONLYFSDIRS, _
        InitialFolder)

    If Not F Is Nothing Then
        BrowseFolder = F.Items.Item.Path
    End If

End Function

Sub z_Combine_Workbooks()
'*******************************************************************************************'
'                                                                                           '
'   Written By:     Anotherhiggins                                                          '
'   Written On:     2006-01-20                                                              '
'   Updated On:     2006-04-05 - Added code to search for folder (stole this bit from web)  '
'                                                                                           '
'   Usage:          Combines data from all excel files found in a selected                  '
'                   folder into a single workbook.                                          '
'                   Code will ask if files have headers                                     '
'                                                                                           '
'*******************************************************************************************'

Application.ScreenUpdating = False

Dim fs
Set fs = Application.FileSearch

Dim MyPath As String

'   Allows user to type in (or copy'n'paste) the folder structure
'*****************************************************************************
MyPath = InputBox("Please type the path of the folder that contains" & _
    " the Excel spreadsheets that you want to combine" & _
    Chr(10) & Chr(10) & _
    "If you would rather browse for a folder, " & _
    "then press ""Cancel""", "Enter Path")

'   If user doesn't enter a folder path, they can browse for the folder
'*****************************************************************************
If MyPath = "" Then
    MyPath = BrowseFolder("Select a folder", "C:\InitialFolder")
        If MyPath = "" Then
            MsgBox "You didn't select a folder", vbCritical, "No folder Selected"
            Exit Sub
        End If
End If

'   Report back on what folder was selected, give user a chance to cancel
'*****************************************************************************
varContinue = MsgBox("You selected: " & MyPath & _
    Chr(10) & Chr(10) & _
    "Would you like to continue?", vbQuestion + vbYesNo)
If varContinue = vbNo Then Exit Sub

'   Open first file
'*****************************************************************************
With fs
    .LookIn = MyPath
    .Filename = "*.xls"
    If .Execute = 0 Then GoTo NoFilesFound
    If .Execute = 1 Then GoTo OnlyOneFileFound
    .Execute
        Workbooks.Open .FoundFiles(1)
            CombinedWBName = ActiveWorkbook.name
        Range("a1").End(xlDown).Offset(1).Select

'   Open the rest of the files
'*****************************************************************************

'   Ask if there are header rows
'*****************************************************************************
    varheader = MsgBox("Do your files contain header rows?", _
        vbQuestion + vbYesNo, "Header Rows?")

'   If there are header rows, then copy from second row
'*****************************************************************************
        If varheader = vbYes Then
            For i = 2 To .FoundFiles.Count
                Workbooks.Open .FoundFiles(i)
                CurrentWBName = ActiveWorkbook.name
                Range(Range("a2"), _
                    Range("a2").SpecialCells(xlCellTypeLastCell)).Copy
                Windows(CombinedWBName).Activate
                ActiveSheet.Paste
                Selection.End(xlDown).Offset(1).Select
                Application.CutCopyMode = False
                Windows(CurrentWBName).Close
            Next i

'   If there are NOT header rows, then copy from the first row
'*****************************************************************************
        Else
            For i = 2 To .FoundFiles.Count
                Workbooks.Open .FoundFiles(i)
                CurrentWBName = ActiveWorkbook.name
                Range(Range("a1"), _
                    Range("a1").SpecialCells(xlCellTypeLastCell)).Copy
                Windows(CombinedWBName).Activate
                ActiveSheet.Paste
                Selection.End(xlDown).Offset(1).Select
                Application.CutCopyMode = False
                Windows(CurrentWBName).Close
            Next i
        End If

End With

'   Save file in the same folder with date/time stamp
'*****************************************************************************
ActiveWorkbook.SaveAs MyPath & "\" & Format(Now(), "yyyymmddhhmmss") & _
    "_CombinedFile.xls"

Set fs = Nothing
Application.ScreenUpdating = True

Exit Sub

'   If no Excel files are found
'*****************************************************************************
NoFilesFound:
MsgBox _
    "No Excel Files were found in that folder." & _
    Chr(10) & Chr(10) & _
    "This code only combines Excel Files.", _
    vbCritical + vbOKOnly, "No Files Found!"
Exit Sub

'   If only one Excel file is found
'*****************************************************************************
OnlyOneFileFound:
MsgBox _
    "Only one Excel File was found in that folder." & _
    Chr(10) & Chr(10) & _
    "This code combines MULTIPLE Excel Files.", _
    vbCritical + vbOKOnly, "Not Enough Files Found!"
End Sub

[tt]_____
[blue]-John[/blue][/tt]
[tab][red]The plural of anecdote is not data[/red]

Help us help you. Please read FAQ 181-2886 before posting.
 
I'm sorry, I completely forgot to list the error. It's 1004 - Application-defined or Object-defined error. Usually I only get that when I'm trying to access "Row 0" or something.

The macro stops halfway through, where it's already added the new worksheet to my current workbook, named it, and begun pasting data. The data just stops when it hits the cell with too many characters.

I will try your code and see if that helps. Thank you!
 



John said:
On what line of code does it return the error?

Skip,
[sub]
[glasses] When a group touring the Crest Toothpaste factory got caught in a large cooler, headlines read...
Tooth Company Freeze a Crowd! and
Many are Cold, but Few are Frozen![tongue][/sub]
 
I didn't know the error line number before, but I just turned off my error handling and tried it again. The line number is Line 103: "destrange.Value = SourceRange.Value
 




What is the RANGE of SourceRange and DestRange?

You'll get an error if SourceRange is a multi-cell range. (what is SourceRange.Value in that case? A multi-cell range does not have Value as a property; it has an array of values.)

Skip,
[sub]
[glasses] When a group touring the Crest Toothpaste factory got caught in a large cooler, headlines read...
Tooth Company Freeze a Crowd! and
Many are Cold, but Few are Frozen![tongue][/sub]
 
But why do I only get an error with cells containing too many characters? The other times I run the macro, the SourceRange would seem to be multi-cell (again, I did not write this original code), and everything runs fine.
 



Hmmmmm...

I just proved my statement to you incorrect regarding the error. I get an error after the character count exceeds 911 in one cell. Eerie!

???

Skip,
[sub]
[glasses] When a group touring the Crest Toothpaste factory got caught in a large cooler, headlines read...
Tooth Company Freeze a Crowd! and
Many are Cold, but Few are Frozen![tongue][/sub]
 
Well, I *think* I've fixed it by replacing the line:

Code:
destrange.Value = SourceRange.Value

with:

Code:
SourceRange.Copy
destrange.PasteSpecial

It seems to be pasting the larger cells now. Weird.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top