كيف يمكنني العثور على اسم عمود Excel الذي يتوافق مع عدد صحيح معين؟[ينسخ]
-
09-06-2019 - |
سؤال
هذا السؤال لديه بالفعل إجابة هنا:
كيف يمكنك تحديد اسم العمود (على سبيل المثال؟"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.يجب أن تعمل مع الإصدارات السابقة التي تدعم الخلايا (...).عنوان وظيفة:
- للعمود الثامن والعشرين - أخذ
columnNumber=28
;Cells(1, columnNumber).Address
عائدات"$AB$1"
. - القيام بالانقسام على
$
تقوم العلامة بإرجاع المصفوفة:["","AB","1"]
- لذا
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+عمود())