2013-01-10 21 views
0

我正在使用Excel 2007,它支持最多16,384列的列。我想获得列名对应的列号。在Excel中将Excel列号转换为列名

目前,我正在使用下面的代码。但是,此代码最多支持256列。任何想法如何获得列名,如果列数大于256

function loc = xlcolumn(column) 

    if isnumeric(column) 
     if column>256 
      error('Excel is limited to 256 columns! Enter an integer number <256'); 
     end 
     letters = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; 
     count = 0; 
     if column-26<=0 
      loc = char(letters(column)); 
     else 
      while column-26>0 
       count = count + 1; 
       column = column - 26; 
      end 
      loc = [char(letters(count)) char(letters(column))]; 
     end 

    else 
     letters = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']; 
     if size(column,2)==1 
      loc =findstr(column,letters); 
     elseif size(column,2)==2 
      loc1 =findstr(column(1),letters); 
      loc2 =findstr(column(2),letters); 
      loc = (26 + 26*loc1)-(26-loc2); 
     end 
    end 

感谢

+1

快速谷歌搜索“matlab excel列”给出了文件交换中的几个文件。 – Squazic

回答

2

一样,声东击西,这里是一个全功能的手柄例如,(几乎)不需要基于文件的功能。这是基于dec2base函数的,因为Excel列名是(几乎)基于26个数字,令人沮丧的是没有“0”字符。

注意:这可能是一个可怕的想法整体,但它的工作原理。文件交换中其他地方可能会找到更好的解决方案。

首先,我不能得到一个基于文件的函数,来执行任意深度函数组合。

function result = compose(fnHandles) 
%COMPOSE Compose a set of functions 
% COMPOSE({fnHandles}) returns a function handle consisting of the 
% composition of the cell array of input function handles. 
% 
% For example, if F, G, and H are function handles with one input and 
% one output, then: 
%  FNCOMPOSED = COMPOSE({F,G,H}); 
%  y = FNCOMPOSED(x); 
% is equivalent to 
%  y = F(G(H(x))); 
if isempty(fnHandles) 
    result = @(x)x; 
elseif length(fnHandles)==1 
    result = fnHandles{1}; 
else 
    fnOuter  = fnHandles{1}; 
    fnRemainder = compose(fnHandles(2:end)); 
    result = @(x)fnOuter(fnRemainder(x)); 
end 

然后,base26值转换为正确的字符串怪异,做作路径

%Functions leading to "getNumeric", which creates a numeric, base26 array 
remapUpper = @(rawBase)(rawBase + (rawBase>='A')*(-55));   %Map the letters 'A-P' to [10:26] 
reMapLower = @(rawBase)(rawBase + (rawBase<'A')*(-48));   %Map characters '' to [0:9] 
getRawBase = @(x)dec2base(x, 26); 

getNumeric = @(x)remapUpper(reMapLower(getRawBase(x))); 

%Functions leading to "correctNumeric" 
% This replaces zeros with 26, and reduces the high values entry by 1. 
% Similar to "borrowing" as we learned in longhand subtraction 
borrowDownFrom = @(x, fromIndex) [x(1:(fromIndex-1)) (x(fromIndex)-1) (x(fromIndex+1)+26) (x((fromIndex+2):end))]; 
borrowToIfNeeded = @(x, toIndex) (x(toIndex)<=0)*borrowDownFrom(x,toIndex-1) + (x(toIndex)>0)*(x); %Ugly numeric switch 

getAllConditionalBorrowFunctions = @(numeric)arrayfun(@(index)@(numeric)borrowToIfNeeded(numeric, index),(2:length(numeric)),'uniformoutput',false); 
getComposedBorrowFunction = @(x)compose(getAllConditionalBorrowFunctions(x)); 

correctNumeric = @(x)feval(getComposedBorrowFunction(x),x); 

%Function to replace numerics with letters, and remove leading '@' (leading 
%zeros) 
numeric2alpha = @(x)regexprep(char(x+'A'-1),'^@',''); 

%Compose complete function 
num2ExcelName = @(x)arrayfun(@(x)numeric2alpha(correctNumeric(getNumeric(x))), x, 'uniformoutput',false)'; 

现在测试使用一些强调转变:

>> num2ExcelName([1:5 23:28 700:704 727:729 1024:1026 1351:1355 16382:16384]) 
ans = 
'A' 
'B' 
'C' 
'D' 
'E' 
'W' 
'X' 
'Y' 
'Z' 
'AA' 
'AB' 
'ZX' 
'ZY' 
'ZZ' 
'AAA' 
'AAB' 
'AAY' 
'AAZ' 
'ABA' 
'AMJ' 
'AMK' 
'AML' 
'AYY' 
'AYZ' 
'AZA' 
'AZB' 
'AZC' 
'XFB' 
'XFC' 
'XFD' 
0

这个功能我写的作品对任何列数(直到Excel用完列)。它只需要一个列号输入(例如,16368将返回一个字符串'XEN')。

如果这个概念的应用与我的函数不同,需要注意的一点是,x的A个列的每一个以26 ^(x-1)+ 26 ^(x-2)+ ... + 26^2 + 26 + 1(例如 'AAA' 开始于26^2 + 26 + 1 = 703)

function [col_str] = let_loc(num_loc) 
test = 2; 
old = 0; 
x = 0; 
while test >= 1 
    old = 26^x + old; 
    test = num_loc/old; 
    x = x + 1; 
end 
num_letters = x - 1; 
str_array = zeros(1,num_letters); 
for i = 1:num_letters 
    loc = floor(num_loc/(26^(num_letters-i))); 
    num_loc = num_loc - (loc*26^(num_letters-i)); 
    str_array(i) = char(65 + (loc - 1)); 
end 
col_str = strcat(str_array(1:length(str_array))); 
end 

希望这可以节省一些有人时间!