Vra

    

Hierdie vraag het reeds 'n antwoord hier:

         

Hoe sou jy die naam kolom (bv "AQ" of "BH") van die nde kolom in Excel te bepaal?

Edit: 'n Taal-agnostikus algoritme om dit te bepaal is die hoofdoel hier

.
Was dit nuttig?

Oplossing

Ek het een keer hierdie funksie om daardie presiese taak uit te voer:

public static string Column(int column)
{
    column--;
    if (column >= 0 && column < 26)
        return ((char)('A' + column)).ToString();
    else if (column > 25)
        return Column(column / 26) + Column(column % 26 + 1);
    else
        throw new Exception("Invalid Column #" + (column + 1).ToString());
}

Ander wenke

Hier is die skoonste korrekte oplossing wat ek kon kom met (in Java, maar voel vry om jou gunsteling taal te gebruik):

String getNthColumnName(int n) {
    String name = "";
    while (n > 0) {
        n--;
        name = (char)('A' + n%26) + name;
        n /= 26;
    }
    return name;
}

Maar moet asseblief laat my weet van as jy 'n fout in die kode te vind, dankie.

'n taal agnostikus algoritme sal as volg wees:

function getNthColumnName(int n) {
   let curPower = 1
   while curPower < n {
      set curPower = curPower * 26
   }
   let result = ""
   while n > 0 {
      let temp = n / curPower
      let result = result + char(temp)
      set n = n - (curPower * temp)
      set curPower = curPower / 26
   }
   return result

Hierdie algoritme neem ook in ag as Excel weer kry opgegradeer na meer as 16k kolomme hanteer. As jy regtig wil om oorboord te gaan, kan jy slaag in 'n bykomende waarde en die gevalle van 26 vervang met 'n ander nommer alternatiewe alfabette akkommodeer

Dankie, Joseph Sturtevant! Jou kode werk perfek - ek dit nodig gehad het in VBScript, so gedink ek sou my weergawe te deel:

Function ColumnLetter(ByVal intColumnNumber)
    Dim sResult
    intColumnNumber = intColumnNumber - 1
    If (intColumnNumber >= 0 And intColumnNumber < 26) Then
        sResult = Chr(65 + intColumnNumber)
    ElseIf (intColumnNumber >= 26) Then
        sResult = ColumnLetter(CLng(intColumnNumber \ 26)) _
                & ColumnLetter(CLng(intColumnNumber Mod 26 + 1))
    Else
        err.Raise 8, "Column()", "Invalid Column #" & CStr(intColumnNumber + 1)
    End If
    ColumnLetter = sResult
End Function

Joseph se kode is goed, maar as jy nie wil hê of nodig het om 'n VBA funksie te gebruik, probeer hierdie.

As ons aanneem dat die waarde van N is in sel A2 Gebruik hierdie funksie:

=MID(ADDRESS(1,A2),2,LEN(ADDRESS(1,A2))-3)
IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))

Dit werk 2 briewekolomme (tot kolom ZZ). Jy wil om nes te hê 'n ander as verklaring vir 3 briewekolomme.

Die formule hierbo versuim op kolomme AY, AZ en elk van die volgende nY en nZ kolomme. Die reggestel formule is:

=IF(COLUMN()>26,CHAR(ROUNDDOWN((COLUMN()-1)/26,0)+64)&CHAR(MOD((COLUMN()-1),26)+65),CHAR(COLUMN()+64)

Van WCM:

As jy nie wil hê om VBA gebruik, kan jy dit gebruik vervang colnr met die nommer wat jy wil

=MID(ADDRESS(1,colnr),2,LEN(ADDRESS(1,colnr))-3)

Let asseblief bewus wees van die feit dat hierdie formule is wisselvallig as gevolg van die gebruik van die ADRES funksie. Vlugtige funksies is funksies wat herbereken deur excel na elke verandering. Gewoonlik uitblink rekent formule se net vir hulle afhanklik verwysings veranderinge.

Dit kan 'n prestasie moordenaar wees, om hierdie formule gebruik.

En hier is 'n omskakeling van die VBScript weergawe te SQL Server 2000 +.

CREATE FUNCTION [dbo].[GetExcelColRef] 
(
    @col_seq_no int
)
RETURNS varchar(5)
AS
BEGIN

declare @Result varchar(5)
set @Result = ''
set @col_seq_no = @col_seq_no - 1
If (@col_seq_no >= 0 And @col_seq_no < 26) 
BEGIN
    set @Result = char(65 + @col_seq_no)
END
ELSE
BEGIN
    set @Result = [dbo].[GetExcelColRef] (@col_seq_no / 26) + '' + [dbo].[GetExcelColRef]  ((@col_seq_no % 26) + 1)
END
Return @Result

END
GO

Ruby one-liner:

def column_name_for(some_int)
    some_int.to_s(26).split('').map {|c| (c.to_i(26) + 64).chr }.join # 703 => "AAA"
end

Dit vat die heelgetal te base26 split dit dan en doen 'n paar wiskunde elke karakter te omskep van ascii. Ten slotte sluit 'em almal weer saam. Geen verdeeldheid, modulus, of rekursie.

Fun.

Dit werk goed in MS Excel 2003-2010. Moet werk vir vorige weergawes ondersteun die selle (...). -adres funksie:

  1. Vir die 28ste kolom - neem columnNumber=28; Cells(1, columnNumber).Address terug "$AB$1".
  2. Doen 'n split op die $ teken gee die skikking: ["","AB","1"]
  3. So Split(Cells(1, columnNumber).Address, "$")(1) gee jou die naam kolom "AB".

UPDATE:

Geneem uit Hoe om Excel kolom getalle te omskep in alfabetiese karakters

' The following VBA function is just one way to convert column number 
' values into their equivalent alphabetical characters:

Function ConvertToLetter(iCol As Integer) As String
   Dim iAlpha As Integer
   Dim iRemainder As Integer
   iAlpha = Int(iCol / 27)
   iRemainder = iCol - (iAlpha * 26)
   If iAlpha > 0 Then
      ConvertToLetter = Chr(iAlpha + 64)
   End If
   If iRemainder > 0 Then
      ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64)
   End If
End Function

van toepassing op: Microsoft Office Excel 2007 SE / 2002 SE / 2000 SE / 97 SE

Ek dink jy VBA-kode moet:

Public Function GetColumnAddress(nCol As Integer) As String

Dim r As Range

Set r = Range("A1").Columns(nCol)
GetColumnAddress = r.Address

End Function

Dit doen wat jy wil in VBA

Function GetNthExcelColName(n As Integer) As String
    Dim s As String
    s = Cells(1, n).Address
    GetNthExcelColName = Mid(s, 2, InStr(2, s, "$") - 2)
End Function

Dit lyk in werk vb.net

Public Function Column(ByVal pColumn As Integer) As String
    pColumn -= 1
    If pColumn >= 0 AndAlso pColumn < 26 Then
        Return ChrW(Asc("A"c) + pColumn).ToString
    ElseIf (pColumn > 25) Then
        Return Column(CInt(math.Floor(pColumn / 26))) + Column((pColumn Mod 26) + 1)
    Else
    stop
        Throw New ArgumentException("Invalid column #" + (pColumn + 1).ToString)
    End If
End Function

Ek het Josef se en dit getoets om BH, dan gevoed dit 980-1000 en dit lyk goed.

In VBA, in die veronderstelling lCol is die kolom nommer:

function ColNum2Letter(lCol as long) as string
    ColNum2Letter = Split(Cells(1, lCol).Address, "$")(0)
end function

Al hierdie kode monsters wat hierdie goeie mense kyk fyn gepos.

Daar is een ding om bewus te wees van. Begin met Office 2007, Excel het eintlik tot 16.384 kolomme. Dit kom neer op XFD (die ou maksimum van 256 pilare was IV). Jy sal hê om hierdie metodes ietwat verander om hulle te laat werk vir drie karakters.

Indien nie so moeilik wees ...

Hier is Gary Waters oplossing

Function ConvertNumberToColumnLetter2(ByVal colNum As Long) As String
    Dim i As Long, x As Long
    For i = 6 To 0 Step -1
        x = (1 - 26 ^ (i + 1)) / (-25) - 1 ‘ Geometric Series formula
        If colNum > x Then
            ConvertNumberToColumnLetter2 = ConvertNumberToColumnLetter2 & Chr(((colNum - x - 1)\ 26 ^ i) Mod 26 + 65)
        End If
    Next i
End Function

via http: //www.dailydoseofexcel com / argief / 2004/05/21 / kolom-nommers-tot-letters /

Met inagneming van die kommentaar van WCM (top waarde = xfd), kan jy dit bereken soos volg;

function IntToExcel(n: Integer); string;
begin
   Result := '';
   for i := 2 down to 0 do 
   begin
      if ((n div 26^i)) > 0) or (i = 0) then
         Result := Result + Char(Ord('A')+(n div (26^i)) - IIF(i>0;1;0));
      n := n mod (26^i);
   end;
end;

Daar is 26 karakters in die alfabet en ons het 'n getallestelsel nes blok of binêre, net met 'n ongewone karakter stel (AZ), verteenwoordig posisioneel die magte van 26: (26 ^ 2) (26 ^ 1) (26 ^ 0).

FYI T-SQL om die naam Excel kolom gegee 'n ordinale (nul-gebaseerde) gee, as 'n enkele verklaring gesê.

Enigiets onder 0 of hoër 16383 (maksimum kolomme in Excel2010) gee terug NULL.

; WITH TestData AS ( -- Major change points
    SELECT -1 AS FieldOrdinal
    UNION ALL
    SELECT 0
    UNION ALL
    SELECT 25
    UNION ALL
    SELECT 26
    UNION ALL
    SELECT 701
    UNION ALL
    SELECT 702
    UNION ALL
    SELECT 703
    UNION ALL
    SELECT 16383
    UNION ALL
    SELECT 16384
)
SELECT
      FieldOrdinal
    , CASE
       WHEN FieldOrdinal < 0     THEN NULL
       WHEN FieldOrdinal < 26    THEN ''
       WHEN FieldOrdinal < 702   THEN CHAR (65 + FieldOrdinal / 26 - 1)
       WHEN FieldOrdinal < 16384 THEN CHAR (65 + FieldOrdinal / 676 - 1)
                                    + CHAR (65 + (FieldOrdinal / 26) - (FieldOrdinal / 676) * 26 - 1)
       ELSE NULL
      END
      + CHAR (65 + FieldOrdinal % 26)
 FROM TestData
 ORDER BY FieldOrdinal

Ek gebruik tans hierdie, maar ek het 'n gevoel dat dit kan geoptimaliseer word.

private String GetNthExcelColName(int n)
{
    String firstLetter = "";  
    //if number is under 26, it has a single letter name
    // otherwise, it is 'A' for 27-52, 'B' for 53-78, etc
    if(n > 26)
    {
        //the Converts to double and back to int are just so Floor() can be used
        Double value = Convert.ToDouble((n-1) / 26);
        int firstLetterVal = Convert.ToInt32(Math.Floor(value))-1;
        firstLetter = Convert.ToChar(firstLetterValue + 65).ToString();
    }    

    //second letter repeats
    int secondLetterValue = (n-1) % 26;
    String secondLetter = Convert.ToChar(secondLetterValue+65).ToString();

    return firstLetter + secondLetter;
}

= CHAR (64 + KOLOM ())

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top