0

最大16,384列の列をサポートするExcel2007を使用しています。列番号に対応する列名を取得したいのですが。

現在、次のコードを使用しています。ただし、このコードは最大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

ありがとう

4

2 に答える 2

3

流用として、これはすべての関数ハンドルの例であり、(ほとんど)ファイルベースの関数は必要ありません。これは関数に基づいていdec2baseます。Excelの列名は(ほぼ)基数26の数値であり、「0」文字がないという苛立たしい違いがあります。

注:これはおそらく全体的にひどい考えですが、機能します。より良い解決策は、おそらくファイル交換の他の場所で見つかります。

まず、任意の深さの関数合成を実行するために、私が回避できなかった1つのファイルベースの関数。

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  '0123456789' 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'
于 2013-01-10T16:31:52.137 に答える
1

私が書いたこの関数は、任意の数の列で機能します(Excelの列がなくなるまで)。列番号の入力が必要なだけです(たとえば、16368は文字列'XEN'を返します)。

この概念の適用が私の関数と異なる場合、Aのx個の列が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

これが誰かの時間を節約することを願っています!

于 2014-06-23T00:34:24.673 に答える