2017-11-02 38 views
1

대량의 파일을 처리하는 데 많은 시간이 걸리기 때문에 matlab에 .xls 파일 가져 오기를 최적화해야합니다. 현재 xlsread 스크립트는 다음과 같습니다.ActiveX를 사용하여 Excel에서 Matlab으로 가져 오기

scriptName = mfilename('fullpath'); 
[currentpath, filename, fileextension]= fileparts(scriptName);  
xlsnames = dir(fullfile(currentpath,'*.xls')); 
xlscount = length(xlsnames); 
xlsimportdata = zeros(7,6,xlscount); 

for k = 1:xlscount 
xlsimport = xlsread(xlsnames(k).name,'D31:I37'); 
xlsimportdata(:,1:size(xlsimport,2),k) = xlsimport; 
end 

처리가 필요한 약 10k 개의 파일이 처리됩니다. 현재 워크 스테이션에서 처리되는 파일 당 2 초, 약 5 시간 30 분이 소요됩니다.

나는 ActiveX가이 목적을 위해 사용될 수 있지만, 현재의 프로그래밍 기술을 훨씬 뛰어 넘으며 다른 곳에서 해결책을 찾을 수 없다는 것을 읽었습니다. 이걸 만드는 방법에 대한 도움을 주시면 감사하겠습니다.

ActiveX (또는 다른 제안 된 방법)를 사용하여 간단하게 수행 할 수있는 경우, 현재 'xlsnames (k, 1) .name'및 'xlsnames'에서 가져온 셀 D5 및 G3의 데이터에도 관심이 있습니다. xlsnames (K, 1) .date '

편집 : 솔루션

% Get path to .m script 
scriptName = mfilename('fullpath'); 
[currentpath, filename, fileextension]= fileparts(scriptName); 

% Generate list of .xls file data 
xlsnames = dir(fullfile(currentpath,'*.xls')); 
xlscount = length(xlsnames); 
SampleInfo = cell(xlscount,2); 
xlsimportdata = cell(7,6,xlscount); 

% Define xls data ranges to import 
SampleID = 'G3'; 
SampleRuntime = 'D5'; 
data_range = 'D31:I37'; 

% Initiate progression bar 
h = waitbar(0,'Initiating import...'); 

% Start actxserver 
exl = actxserver('excel.application'); 
exlWkbk = exl.Workbooks; 

for k = 1:xlscount 

    % Restart actxserver every 100 loops due limited system memory 
    if mod (k,100) == 0 
     exl.Quit 
     exl = actxserver('excel.application'); 
     exlWkbk = exl.Workbooks; 
    end 

    exlFile = exlWkbk.Open([dname filesep xlsnames(k).name]); 
    exlSheet1 = exlFile.Sheets.Item('Page 0'); 

    rngObj1 = exlSheet1.Range(SampleID); 
    xlsimport_ID = rngObj1.Value; 

    rngObj2 = exlSheet1.Range(SampleRuntime); 
    xlsimport_Runtime = rngObj2.Value; 

    rngObj3 = exlSheet1.Range(data_range); 
    xlsimport_data = rngObj3.Value; 

    SampleInfo(k,1) = {xlsimport_ID}; 
    SampleInfo(k,2) = {xlsimport_Runtime}; 
    xlsimportdata(:,:,k) = xlsimport_data; 

    % Progression bar updater 
    progress = round((k/xlscount) * 100); 

    importtext = sprintf('Importing %d of %d', k, xlscount); 
    waitbar(progress/100,h,sprintf(importtext)); 
    disp(['Import progress: ' num2str(k) '/' num2str(xlscount)]); 

end 
%close actxserver 
exl.Quit 

% Close progression bar 
close(h) 
+0

액티브 X는 10K 파일을 열거 나 닫아야합니다. 시간을 절약 할 수 있을지 확신하지 못합니다. 별도의 시트에 적은 수의 파일에 데이터를 저장할 수 있으면 두 방법 모두 속도를 크게 향상시킬 수 있습니다. 그렇지 않다면, 다음 사항을 고려하십시오 : http://www.mathworks.com/matlabcentral/fileexchange/10465-xlswrite1 – Adiel

+0

불행하게도, 나는 그런 옵션을 사용할 수 없습니다. matlab에 가져 오기위한 .xls 파일은 프로덕션 및 실험실의 워크 스테이션에서 실행되는 타사 소프트웨어에서 자동으로 생성 된 보고서 파일입니다. – mendokusai

+0

'xlsread'가 파일을 읽을 때마다 엑셀을 열거 나 닫지 않음으로써 많은 시간을 절약 할 수 있습니다. [여기] (https://www.mathworks.com/matlabcentral/answers/71199-opening-excel-only-once-at-the-beginning-of-the-optimization-proces-in-matlab-and-not)을 참조하십시오. -each-time-matl)을 예로들 수 있습니다. 실제로 이것은 ActiveX 에이전트를 직접 조작하여 수행됩니다. 나는 이것에 대한 내 자신의 기능을 가지고 있지만 지금은 가지고 있지 않습니다. – buzjwa

답변

1

이 사용 해보세요를 반영하기 위해 업데이트되었습니다. 저는 엑셀 엑셀 전문가가 아닙니다. 그러나, 내 작은 양의 테스트 XLS 파일 (3) 나를 위해이 작동합니다. 나는 결코 closeexlWkbk이 아니므로 메모리 사용량이 건물인지 또는 자동으로 정리 된 경우 자동으로 지워지는지 알고 있습니다. 유망한 것으로 보이는 거의 2.5 배의 속도 증가를보고 있습니다.

>> timeit(@getSomeXLS) 
ans = 
    1.8641 

>> timeit(@getSomeXLS_old) 
ans = 
    4.6192 

내가 얼마나 궁금해하니 많은 수의 엑셀 시트에이 의견이 있으면 의견을 남겨주세요.

function xlsimportdata = getSomeXLS() 

scriptName = mfilename('fullpath'); 
[currentpath, filename, fileextension]= fileparts(scriptName); 
xlsnames = dir(fullfile(currentpath,'*.xls')); 
xlscount = length(xlsnames); 
xlsimportdata = zeros(7,6,xlscount); 
exl = actxserver('excel.application'); 

exlWkbk = exl.Workbooks; 
dat_range = 'D31:I37'; 

for k = 1:xlscount 
    exlFile = exlWkbk.Open([currentpath filesep xlsnames(k).name]);  
    exlSheet1 = exlFile.Sheets.Item('Sheet1'); %Whatever your sheet is called. 
    rngObj = exlSheet1.Range(dat_range); 
    xlsimport = cell2mat(rngObj.Value); 
    xlsimportdata(:,:,k) = xlsimport; 
end 
exl.Quit 
+0

이 솔루션은 훌륭하게 작동합니다. 100 개의 파일을 테스트했으며 3.85x 속도 향상 (177 초 xlsread 대 46 초 activex)을 발견했습니다. 메모리 사용 문제가 발생하지 않았습니다. 스크립트를 i5-5300U에서 8GB RAM으로 실행하십시오. – mendokusai

+0

이 주석을 수정해야합니다. 가져 오기 중에 메모리 사용량이 지속적으로 증가하기 때문에 수백 개 이상의 파일에 사용되는 경우이를위한 솔루션이 필요합니다. – mendokusai

+0

아마도 100 회 반복마다 또는 메모리에 많은 호출이 종료되고 actxserver를 다시 시작해야할까요? 내가 메모리를 깨끗이 할 때 100 % 확실하지만 그만한 가치가 있다고 말했듯이. 루프 안쪽에'mod (k, 100) == 0' exl.quit과 같은 것을 추가하십시오. 그래서 이제는 아무 것도 시도 할 수 없습니다. –