0 前言
上一篇文章,講到使用Matlab讀寫Excel的各種方式,比如xlsread和xlswrite,還有actxserver,Matlab調用Excel宏,Excel調用Matlab,simulink處理excel的子產品等等。
不了解的可以看下這篇文章:
szyyy:MATLAB造輪子7_MATLAB讀寫EXCEL的相關操作zhuanlan.zhihu.com
MATLAB造輪子7_MATLAB讀寫EXCEL的相關操作mp.weixin.qq.com
在使用Matlab處理Excel資料的時候,有時常常需要先擷取Excel單元格的位置,然後再執行讀取或寫入的操作,比如xlsread和xlswrite兩個函數中的xlRange,還有actxserver函數。
在使用Matlab處理Excel資料的時候,有時常常需要先擷取Excel單元格的位置,然後再執行讀取或寫入的操作,比如xlsread和xlswrite兩個函數中的xlRange,還有actxserver函數。
以前的做法,通常是先對要處理的資料做個初步統計,記錄下要讀取或者寫入的單元格位址範圍,做個宏定義,然後在讀取或寫入的代碼中,調用這個宏定義。
這種方式,對于資料格式确定,或者不頻繁讀取寫入的資料,可能還不是太麻煩,但遇上需要批量讀取或寫入不同範圍大小的資料時,就無法執行自動化操作了,怎麼能夠自動識别單元格的位置或範圍?下面就講講大概的思路和代碼。
1 主要思路
一種情況是,在向excel檔案寫入資料時,我們先知道資料的長度或大小,然後想把長度或大小直接轉換成單元格的範圍值xlRange。
比如一個16個資料的行向量,想寫入到第一行,B 列為起始位置,則xlRange="B1:M16"。
另一種情況是,知道了單元格的範圍或者位置,想把字元轉換為數字。
比如"AA1",代表的是第一行,第27列的位置。
是以,以上主要會用到的函數有:
abs(str)和char(num),分别是将字元轉化為數字,數字轉化為字元。
其實主要就是ASCII碼的轉化,可以簡單測試下功能:
abs('Z') = 90 = 26 + 64;
abs('ABC') = [65 66 67];
char(1+64) = 'A';
char([65 66 67]) = ‘ABC’;
轉換多個字元串或數字的思路,可以先判斷字元或數字計算長度,然後使用循環,一個個轉換,最後再對字元或數字進行拼接就行了。另外,A到Z的字母排列,每隔26個就有一定的規律,類似26進制。
% 26進制法
% AB: 26進制可以表示為
(abs('A')-64)*26^1 + (abs('B')-64)*26^0 = 1*26^1+2*26^0 = 28
% ABC: 26進制可以表示為
(abs('A')-64)*26^2+(abs('B')-64)*26^1+(abs('C')-64)*26^1
= 1*26^2+2*26^1 + 3*26^1 = 731
這樣,數字轉字元串時,就可以使用除法或mod,不斷地計算除以26之後的餘數獲得對應的字元,然後再拼接各個字元就可以了。
同樣地,字元串轉數字時,不斷地對每一位,進行26的幂運算,然後累加,就可以獲得最終的數字了。
具體可以看以下代碼。
2 代碼實作
提供了思路後,具體的代碼實作,并不太複雜了,隻要再做些防錯的檢測等,確定輸入是數字或者字元,就可以執行數字或字元的轉換了。(另外,要注意判斷整除為0時,其實是Z)檢測輸入的是否為數字,可以使用:
ifisa(InputNum,'numeric');檢測輸入的是否為數字,可以使用:
ischar(InputStr);另外,數字或字元的翻轉,可以使用:
InputStr_2 = InputStr(end:-1:1);或者
InputStr_2= rot90(InputStr,2);具體可以參考以下代碼,大部分已經做了注釋。
Excel單元格_數字轉字元串:
% Func1: Excel_Num2Str
% Author: qcgcsrc
% Date: 20200419
%% TestCase
% A = Excel_Num2Str(1);
% AZ = Excel_Num2Str(52);
% Z = Excel_Num2Str(26);
% ZA = Excel_Num2Str(677);
% 1-A, 2-B, ...,26-Z,27-AA
function [OutStr] = Excel_Num2Str(InputNum)
ifisa(InputNum,'numeric') % 判斷輸入的是否為數字
x = InputNum;
x2_char = '';
while x > 0
x1 = mod(x, 26); % 不斷對x執行取模(取餘數)
if x1==0 % 如果餘數0,則能被26整除,代表Z
x1 = 26;
end
x1_char = char(x1 + 64); % 得到對應數字的字元(1:A),加上64
x = (x - x1)/26; % 得到一個新的x ()
x2_char = [x2_char x1_char];
end
OutStr = rot90(x2_char,2);
end
end
Excel單元格_字元串轉數字:
% Func2: Excel_Str2Num
% Author: qcgcsrc
% Date: 20200419
%% TestCase
% Excel_Str2Num('ABCD'): 19010
% Excel_Str2Num('ABC'): 731
% Excel_Str2Num('AA'): 27
% Excel_Str2Num('Z'): 26
% A-1, B-2, ...,Z-26,AA-27
function [OutNum] = Excel_Str2Num(InputStr)
OutNum = 0;
if ischar(InputStr) % 判斷輸入的是否為字元
lens_Str = length(InputStr); % 計算字元長度
InputStr_2 = InputStr(end:-1:1); % 将字元翻轉(ABC->CBA)
%InputStr_2 = rot90(InputStr,2); % 将字元翻轉2(ABC->CBA)
for N1 = 1 : 1 : lens_Str % 從字元最後一個開始轉換
strNum = abs(InputStr_2(N1)) - 64; % 'A'-> 65-> 1
OutNum = OutNum + strNum * 26^(N1-1); % ABC
end
end
end
3 總結
有了以上函數代碼,就可以在擷取資料的長度後,直接拼接出寫入xls單元格範圍的字元串。
針對資料長度變化或者單元格位址範圍變化,隻要再加些代碼,就能自動化的計算出新的範圍位址,再也不用一個個手動計算了。
如下所示為示例代碼:
%% 或者資料長度後,計算xls單元格的範圍位址
lens_SpdRow = length(Table_Spd);
lens_TrqCol = length(Table_Trq3);
% B20:Q20
strRange_SpdRow = strcat(Excel_Num2Str(2), num2str(lens_TrqCol+1),':',...
Excel_Num2Str(2+lens_SpdRow-1), num2str(lens_TrqCol+1));
% A1:A19
strRange_TrqCol = strcat(Excel_Num2Str(1),num2str(1),':',...
Excel_Num2Str(1), num2str(lens_TrqCol));
sheet2.Range(strRange_SpdRow).Value = Table_Spd; %
sheet2.Range(strRange_TrqCol).Value = Table_Trq3; %
% sheet.Range(strRange).Value = data;
% sheet.Range(strcat('A', num2str(lens_Trq)).Value = Table_Spd; %
% sheet.Range('B20: Q20').Value = Table_Spd; %
% sheet.Range('A19: A1').Value = Table_Trq3; % 360:20
好了,本期就先分享到這,下次有機會再分享MATLAB和Excel相關的一些操作。
本文相關的代碼已經基本都在文章裡了,如需要源碼的朋友,可以到背景留言,或者回複"
Excel單元格位址範圍" 擷取。