2016-12-09 4 views
0

Я пытаюсь объединить несколько больших файлов Excel в один файл, используя следующий кодCosolidating большие файлы Excel, не могу обойти переполнение буфера

Sub Macro1() 
    Application.DisplayAlerts = False 
    Dim Country As String 
    Dim i As Integer 
    Dim j As Integer 
    Dim k As Integer 

    k = 2 
    For i = 1 To 50 
     Windows("Try2").Activate 
     Country = Worksheets("Names").Cells(i, 1).Value 
     Workbooks.Open Filename:= "C:path\" & Country & " " 
     ActiveWorkbook.Sheets("Main").Activate 
     finalrow = Cells(Rows.Count, 1).End(xlUp).Row 

     Workbooks(Country).Sheets("Main").Range(Cells(1, 1), Cells(10000, 64)).Copy 
     Workbooks("Try2").Sheets("Output").Activate 
     Workbooks("Try2").Sheets("Output").Cells(k, 2).PasteSpecial xlPasteValues 
     Range(Cells(k, 1), Cells(k + 10000, 1)) = Country 
     finalrow2 = 10002 + k 
     k = finalrow2 + 1 
     Workbooks(Country).Sheets("Main").Activate 
     Workbooks(Country).Close SaveChanges:=False 
    Next i 
End Sub 

Однако после консолидации 2-3 файлов первенствует это бросает переполнение буфера ошибка. У нас около 50 файлов. Я пытаюсь понять, если это просто проблема с excel, неспособным обрабатывать большие файлы или что-то не так с моим кодом. Есть ли способ управлять Excel для обработки больших размеров файлов?

+0

Попробуйте использовать что-то вдоль этих строк вместо копии pastespecial 'application.Workbooks (2) .ActiveSheet.range ("a1: c5"). Value = application.Workbooks (1) .ActiveSheet.range ("a1: c5"). Value' –

+0

Мне жаль, что я не могу обернуть голову вокруг вашего предложения , Извинения –

+3

вы также объявили переменные как целые числа, я не уверен, сколько строк вы собираетесь в консолидации, но если они превышают предел целых чисел 32767 в excel, он вернет ошибку переполнения, попробуйте объявить их как 'long' –

ответ

3

Здесь есть несколько вещей, которые могут отбросить ваш макрос.

Во-первых, вы объявляете i, j и k как тип данных «целочисленный»; проблема заключается в том, что наибольшее возможное значение, которое может иметь целое число, составляет 32 767. Если вы перейдете к этому, вы получите переполнение буфера.

Во-вторых, вы объявляете переменные, которые вы не используете, а не объявляете переменные, которые вы используете. Насколько я вижу, j не используется нигде в коде, но используются finalrow и finalrow2, но не объявлены нигде.

Я бы посоветовал вам заменить ваши типы данных integer, которые могут быть очень высокими с long типами данных (длинное целое число). Вы также можете использовать более описательные имена для целых чисел, чтобы сделать код более удобным для чтения:

Dim iCycler as integer 
Dim kStart as long 
Dim FinalRow as Long 
Dim FinalRow2 as Long 

Запуск через это и посмотреть, что получится.

отредактирован ADD:

Вот полный процесс, который должен удовлетворить вас:

Sub Duplicator() 

    'Define the source file, sheet, and range 
    Dim wbkSource As Workbook 
    Dim shtSource As Worksheet 
    Dim rngSource As Range 
    'Define the target file, sheet and range 
    Dim wbkTarget As Workbook 
    Dim shtTarget As Worksheet 
    Dim rngTarget As Range 
    'Define the sheet with the list of countries 
    Dim shtControl As Worksheet 
    'Prepare control integers 
    Dim iLoop As Integer 
    Dim lLastRow As Long 

    'Define the target file as the active workbook 
    Set wbkTarget = ActiveWorkbook 
    Set shtTarget = wbkSource.Sheets("Output") 
    Set rngTarget = shtTarget.Range("A2") 
    Set shtControl = wbkTarget.Sheets("Names") 

    'Loop through the list 
    For iLoop = 1 To 50 
     'Open the source file and assign it to a variable. 
     Set wbkSource = Workbooks.Open("C:\path\" & shtControl.Cells(iLoop, 1).Value) 
     'Assign the source sheet 
     Set shtSource = wbkSource.Sheets("Main") 
     'Find the last row of data 
     lLastRow = shtSource.Range("A" & Rows.Count).End(xlUp).Row 
     'Use the last row to build a source range variable 
     Set rngSource = shtSource.Range("A1", "BL" & lLastRow) 
     'Check that there is space for the copy. If there is not, create a new sheet for the new data 
     If rngTarget.Row + lLastRow > shtTarget.Rows.Count Then 
      Set shtTarget = wbkTarget.Sheets.Add 
      shtTarget.Name = "Output 2" 
      Set rngTarget = shtTarget.Range("A2") 
     End If 
     'Use the size of rngSource to define the size of the target range 
     Set rngTarget = rngTarget.Resize(rngSource.Rows.Count, rngSource.Columns.Count) 
     'Duplicate the values over 
     rngTarget.Value = rngSource.Value 
     'Prepare the target range for the next loop 
     Set rngTarget = shtTarget.Range("A" & Rows.Count).End(xlUp).Offset(1, 0) 
     'Close the source file 
     wbkSource.Close False 
    Next iLoop 
End Sub 

Объявив и использования переменных по всему, код должен быть проще и писать и читать. Он также должен работать быстрее, поскольку он использует структуру range1.value = range2.value, которая обходит довольно медленный буфер обмена. Он также содержит проверку, чтобы убедиться, что вы не превзошли 1 048 576 строк данных, что может привести к сбою.

0

вполне по линии хорошей практики кодирования Верфф уже объяснил вам, вы могли бы попробовать это другой (комментировали) код:

Sub Macro1() 
    Dim outputSht As Worksheet '<--| declare a variable to set your "output" sheet to 
    Dim countryData As Variant, countryNames As Variant '<--| declare arrays to store "country names" and "country data" in 
    Dim country As Variant '<-- "countries" looping variable 

    Application.Calculation = xlCalculationManual '<-- disable calculations 
    Application.ScreenUpdating = False '<-- disable screen updating 


    With Workbooks("Try").Worksheets("Names") '<--| reference "country names" worksheet 
     countryNames = Application.Transpose(.Range("A1", .Cells(.Rows.count, 1).End(xlUp)).Value) '<--| store country names in column "A" from row 1 down to last not empty row 
    End With 

    Set outputSht = Workbooks("Try").Worksheets("Output") '<--| set "output" worksheet 
    For Each country In countryNames '<-- loop through countries stored in 'countryNames' 

     With Workbooks.Open(FileName:="C:path\" & Country).Sheets("Main") '<--| open current country workbook and reference its "Main" sheet 
      countryData = .Range("BL1", .Cells(.Rows.count, 1).End(xlUp)).Value '<--| store current country data in 'countryData' array 
      .Parent.Close SaveChanges:=False '<--| close current country workbook 
     End With 

     With outputSht '<--| reference output sheet 
      With .Cells(.Rows.count, 1).End(xlUp).Offset(1).Resize(UBound(countryData, 1)) '<--|reference its column A range from first empty cell after last not empty cell down to as many rows as current country array has 
       .Value = country '<--| write current country name in referenced range 
       .Offset(, 1).Resize(, 64).Value = countryData '<--| write country data array content from column B rightwards 
      End With 
     End With 
    Next country 

    Application.Calculation = xlCalculationAutomatic 
    Application.ScreenUpdating = True 

End Sub 

, поскольку он использует массивы для хранения данных, он страдает от массивов максимального размера ограничение до 65536 строк. Если ваши «страны» в книгах «Основные» листы имеют больше строк, чем такой предел, тогда должны приниматься различные методы вставки значений (например, между значениями диапазона).

 Смежные вопросы

  • Нет связанных вопросов^_^