كيف يمكنني العثور على اسم عمود Excel الذي يتوافق مع عدد صحيح معين؟[ينسخ]

StackOverflow https://stackoverflow.com/questions/22708

سؤال

كيف يمكنك تحديد اسم العمود (على سبيل المثال؟"AQ" أو "BH") للعمود n في Excel؟

يحرر:الهدف الرئيسي هنا هو خوارزمية حيادية اللغة لتحديد هذا.

هل كانت مفيدة؟

المحلول

لقد كتبت هذه الوظيفة ذات مرة لأداء هذه المهمة بالضبط:

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());
}

نصائح أخرى

هنا أنظف صحيح الحل الذي يمكنني التوصل إليه (في Java، ولكن لا تتردد في استخدام لغتك المفضلة):

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

ولكن يرجى إبلاغي إذا وجدت خطأ في هذا الكود، وشكراً.

ستكون الخوارزمية الحيادية للغة كما يلي:

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

تأخذ هذه الخوارزمية أيضًا في الاعتبار إذا تمت ترقية Excel مرة أخرى للتعامل مع أكثر من 16 ألف عمود.إذا كنت تريد المبالغة حقًا، فيمكنك تمرير قيمة إضافية واستبدال مثيلات 26 برقم آخر لاستيعاب الحروف الهجائية البديلة

شكرا، جوزيف ستورتيفانت!الكود الخاص بك يعمل بشكل مثالي - كنت بحاجة إليه في vbscript، لذلك فكرت في مشاركة الإصدار الخاص بي:

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

رمز جوزيف جيد، ولكن إذا كنت لا تريد أو تحتاج إلى استخدام وظيفة VBA، فجرب ذلك.

بافتراض أن قيمة n موجودة في الخلية A2استخدم هذه الوظيفة:

=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))

يعمل هذا على عمودين من الحروف (حتى العمود ZZ).سيتعين عليك دمج عبارة if أخرى لأعمدة مكونة من 3 أحرف.

فشلت الصيغة أعلاه على الأعمدة AY, AZ وكل مما يلي nY و nZ أعمدة.الصيغة المصححة هي:

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

من دبليو سي إم:

إذا كنت لا ترغب في استخدام VBA ، فيمكنك استخدام هذا الاستبدال colnr بالرقم الذي تريده

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

يرجى العلم بأن هذه الصيغة متقلبة بسبب استخدام الدالة ADDRESS.الوظائف المتطايرة هي الوظائف التي يتم إعادة حسابها بواسطة Excel بعد كل تغيير.عادةً ما يقوم Excel بإعادة حساب الصيغة فقط عندما تتغير مراجعها التابعة.

قد يكون استخدام هذه الصيغة قاتلاً للأداء.

وهنا تحويل من إصدار VBScript إلى 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

روبي بطانة واحدة:

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

فهو يحول العدد الصحيح إلى base26 ثم يقسمه ويقوم ببعض العمليات الحسابية لتحويل كل حرف من ascii.أخيرًا ينضم إليهم جميعًا معًا مرة أخرى.لا يوجد تقسيم أو معامل أو العودية.

هزار.

يعمل هذا بشكل جيد في MS Excel 2003-2010.يجب أن تعمل مع الإصدارات السابقة التي تدعم الخلايا (...).عنوان وظيفة:

  1. للعمود الثامن والعشرين - أخذ columnNumber=28; Cells(1, columnNumber).Address عائدات "$AB$1".
  2. القيام بالانقسام على $ تقوم العلامة بإرجاع المصفوفة: ["","AB","1"]
  3. لذا Split(Cells(1, columnNumber).Address, "$")(1) يعطيك اسم العمود "AB".

تحديث:

مأخوذ من كيفية تحويل أرقام أعمدة إكسل إلى أحرف أبجدية

' 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

ينطبق على:مايكروسوفت أوفيس إكسل 2007 SE / 2002 SE / 2000 SE / 97 SE

أفترض أنك بحاجة إلى رمز VBA:

Public Function GetColumnAddress(nCol As Integer) As String

Dim r As Range

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

End Function

هذا يفعل ما تريده في 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

يبدو أن هذا يعمل في 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

أخذت جوزيف واختبرته على BH، ثم أطعمته 980-1000 وكان يبدو جيدًا.

في VBA، بافتراض أن lCol هو رقم العمود:

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

تبدو كل نماذج التعليمات البرمجية هذه التي نشرها هؤلاء الأشخاص الطيبون جيدة.

هناك شيء واحد يجب أن تكون على علم به.بدءًا من Office 2007، أصبح لدى Excel بالفعل ما يصل إلى 16384 عمودًا.يُترجم ذلك إلى XFD (الحد الأقصى القديم البالغ 256 عمودًا كان IV).سيتعين عليك تعديل هذه الأساليب إلى حد ما لجعلها تعمل مع ثلاثة أحرف.

لا ينبغي أن يكون بهذه الصعوبة ...

إليك حل غاري ووترز

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

عبر http://www.dailydoseofexcel.com/archives/2004/05/21/column-numbers-to-letters/

بالنظر إلى تعليق wcm (القيمة العليا = xfd)، يمكنك حسابها بهذه الطريقة؛

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;

هناك 26 حرفًا في الأبجدية ولدينا نظام أرقام تمامًا مثل النظام السداسي أو الثنائي، فقط مع مجموعة أحرف غير عادية (A..Z)، تمثل موضعيًا قوى الرقم 26:(26^2)(26^1)(26^0).

لمعلوماتك T-SQL لإعطاء اسم عمود Excel ترتيبيًا (يعتمد على الصفر)، كعبارة واحدة.

أي شيء أقل من 0 أو أعلى من 16383 (الحد الأقصى للأعمدة في Excel2010) يُرجع 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

أستخدم هذا حاليًا، لكن لدي شعور بأنه يمكن تحسينه.

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+عمود())

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top