записывать информацию в Excel после каждого цикла - PullRequest
1 голос
/ 03 октября 2011

У меня есть матрица 6x7 (A) и некоторые операции, которые я выполняю, для k = 1: 50 (количество циклов). Я знаю, что для записи одной матрицы в файл Excel мне нужно:

xlswrite('Filename.xls', A, 'A1')

Как можно записать информацию после каждого цикла, таким образом, чтобы каждый цикл начинался с позиции A1 + ((k-1) * 6 + 1) в Excel, и у меня есть все результаты матрицы (A), перечисленные один друг за другом.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 04 октября 2011

При использовании функции XLSWRITE вы можете избежать необходимости каждый раз вычислять диапазоны ячеек Excel, указав номер листа и диапазон, где диапазон дает только первую ячейку, с которой начинается.

Это особенно полезно, если матрица меняет размер на каждой итерации; мы просто берем последнюю использованную ячейку и сдвигаем ее на количество строк матрицы.

Пример:

offset = 1;
for i=1:5
    %# generate different size matrices each loop
    A = ones(randi(4),randi(4)).*i;

    %# insert matrix in Excel inside the 1st sheet, starting at cell specifed
    xlswrite('filename.xls', A, 1, sprintf('A%d',offset));

    %# increment offset
    offset = offset + size(A,1);
end

это создает файл Excel со следующим содержимым:

1    1        
1    1        
1    1        
2    2    2    2
3    3
3    3
4            
4            
4            
4            
5    5    5    
5    5    5    
5    5    5    
5    5    5    

Обратите внимание, что соединение с Excel устанавливается, а затем закрывается при каждом вызове XLSWRITE. Это имеет значительные накладные расходы.

Лучшим подходом было бы открыть Excel один раз и повторно использовать один и тот же сеанс для записи всех ваших данных, а затем закрыть его, как только мы закончим. Однако вам придется самостоятельно вызывать функции Office Interop.

Поскольку упомянутая выше уловка теперь не сработает, я буду использовать функцию «Вычислить диапазон Excel» для вычисления диапазонов ячеек (есть много других реализаций FEX).

Вот код (повторное использование некоторого кода из предыдущего ответа ):

%# output file name
fName = fullfile(pwd, 'file.xls');

%# create Excel COM Server
Excel = actxserver('Excel.Application');
Excel.Visible = true;

%# delete existing file
if exist(fName, 'file'), delete(fName); end

%# create new XLS file
wb = Excel.Workbooks.Add();
wb.Sheets.Item(1).Activate();

%# iterations
offset = 0;
for i=1:50
    %# generate different size matrices each loop
    A = ones(randi(4),randi(4)).*i;

    %# calculate cell range to fit matrix (placed below previous one)
    cellRange = xlcalcrange('A1', offset,0, size(A,1),size(A,2));
    offset = offset + size(A,1);

    %# insert matrix in sheet
    Excel.Range(cellRange).Select();
    Excel.Selection.Value = num2cell(A);
end

%# save XLS file
wb.SaveAs(fName,1);
wb.Close(false);

%# close Excel
Excel.Quit();
Excel.delete();

Фактически, я запустил обе версии с 50 итерациями и сравнил время с TIC / TOC:

Elapsed time is 68.965848 seconds.      %# calling XLSWRITE
Elapsed time is 2.221729 seconds.       %# calling Excel COM directly
0 голосов
/ 03 октября 2011

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

Однако, если вы действительно хотите записать это в цикле, должно сработать следующее (при условии, что вы имеете в виду снижение):

range = sprintf('A%i:G%i', (k-1)*6+[1 6]);
xlswrite('Filename.xls', A, range);

Обратите внимание, что это не будет корректироваться автоматически, если A изменит размер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...