Как преобразовать номер столбца (например, 127) в столбец Excel (например, AA)

У вас есть несколько вариантов. Для этого вы можете использовать функции os.path.getmtime и os.path.getctime :

import os.path, time
print("last modified: %s" % time.ctime(os.path.getmtime(file)))
print("created: %s" % time.ctime(os.path.getctime(file)))

Другой вариант - использовать os.stat :

import os, time
(mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(file)
print("last modified: %s" % time.ctime(mtime))

Примечание: ctime() указывает, что not относится к времени создания в системах * nix, а скорее в последний раз, когда изменились данные inode. (спасибо kojiro за то, что этот факт более ясен в комментариях, предоставив ссылку на интересный пост в блоге)

439
задан 3 revs, 3 users 89% 12 September 2015 в 08:39
поделиться

20 ответов

Вот то, как я делаю это:

private string GetExcelColumnName(int columnNumber)
{
    int dividend = columnNumber;
    string columnName = String.Empty;
    int modulo;

    while (dividend > 0)
    {
        modulo = (dividend - 1) % 26;
        columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
        dividend = (int)((dividend - modulo) / 26);
    } 

    return columnName;
}
851
ответ дан Graham 12 September 2015 в 08:39
поделиться

Большинство предыдущих ответов верны. Вот еще один способ преобразования номера столбца в столбцы Excel. Решение довольно простое, если мы думаем об этом как о базовом преобразовании. Просто преобразуйте номер столбца в основание 26, поскольку в нем только 26 букв. Вот как вы можете это сделать:

шаги:

  • установить столбец как частное

  • вычтите одно из фактор-переменной (из предыдущего шага), потому что нам нужно попасть в таблицу ascii , где 97 - это.

  • разделите на 26 и получите остаток.

  • добавьте +97 к остатку и преобразуйте в char (поскольку 97 является «a» в таблице ASCII)
  • частное становится новым частным / 26 (поскольку мы можем перейти через 26 столбцов)
  • продолжайте делать это, пока частное не станет больше 0, а затем верните результат

вот код, который делает это:)

def convert_num_to_column(column_num):
    result = ""
    quotient = column_num
    remainder = 0
    while (quotient >0):
        quotient = quotient -1
        remainder = quotient%26
        result = chr(int(remainder)+97)+result
        quotient = int(quotient/26)
    return result

print("--",convert_num_to_column(1).upper())
0
ответ дан grepit 12 September 2015 в 08:39
поделиться

Это вопрос, который перенаправляют все остальные, а также Google, поэтому я публикую это здесь.

Многие из этих ответов верны, но слишком громоздки для простых ситуаций, например, когда у вас нет более 26 столбцов. Если у вас есть какие-либо сомнения относительно того, что вы можете перейти в двухбуквенные столбцы, тогда проигнорируйте этот ответ, но если вы уверены, что этого не сделаете, вы можете сделать это так же просто, как это в C #:

public static char ColIndexToLetter(short index)
{
    if (index < 0 || index > 25) throw new ArgumentException("Index must be between 0 and 25.");
    return (char)('A' + index);
}

Черт возьми, если вы уверены в том, что вы передаете, вы можете даже удалить проверку и использовать эту строку:

(char)('A' + index)

Это будет очень похоже на многие языки, поэтому вы можете адаптировать ее по мере необходимости.

Опять же, используйте это, только если вы на 100% уверены, что у вас не будет более 26 столбцов .

1
ответ дан Vlad Schnakovszki 12 September 2015 в 08:39
поделиться

Вам может потребоваться преобразование в обе стороны, например, из столбца Excel, например AAZ, в целое число и из любого целого числа в Excel. Два метода ниже сделают именно это. При условии индексации на основе 1, первым элементом в ваших «массивах» является элемент номер 1. Здесь нет ограничений по размеру, поэтому вы можете использовать адреса, такие как ОШИБКА, и это будет номер столбца 2613824 ...

public static string ColumnAdress(int col)
{
  if (col <= 26) { 
    return Convert.ToChar(col + 64).ToString();
  }
  int div = col / 26;
  int mod = col % 26;
  if (mod == 0) {mod = 26;div--;}
  return ColumnAdress(div) + ColumnAdress(mod);
}

public static int ColumnNumber(string colAdress)
{
  int[] digits = new int[colAdress.Length];
  for (int i = 0; i < colAdress.Length; ++i)
  {
    digits[i] = Convert.ToInt32(colAdress[i]) - 64;
  }
  int mul=1;int res=0;
  for (int pos = digits.Length - 1; pos >= 0; --pos)
  {
    res += digits[pos] * mul;
    mul *= 26;
  }
  return res;
}
17
ответ дан 2 revs, 2 users 97% 12 September 2015 в 08:39
поделиться

.. И преобразован в php:

function GetExcelColumnName($columnNumber) {
    $columnName = '';
    while ($columnNumber > 0) {
        $modulo = ($columnNumber - 1) % 26;
        $columnName = chr(65 + $modulo) . $columnName;
        $columnNumber = (int)(($columnNumber - $modulo) / 26);
    }
    return $columnName;
}
8
ответ дан Stephen Fuhry 12 September 2015 в 08:39
поделиться

Если кому-то нужно сделать это в Excel без VBA, есть способ:

=SUBSTITUTE(ADDRESS(1;colNum;4);"1";"")

где colNum - номер столбца

А в VBA:

Function GetColumnName(colNum As Integer) As String
    Dim d As Integer
    Dim m As Integer
    Dim name As String
    d = colNum
    name = ""
    Do While (d > 0)
        m = (d - 1) Mod 26
        name = Chr(65 + m) + name
        d = Int((d - m) / 26)
    Loop
    GetColumnName = name
End Function
59
ответ дан 2 revs 12 September 2015 в 08:39
поделиться

Я использую этого в VB.NET 2003, и он работает хорошо...

Private Function GetExcelColumnName(ByVal aiColNumber As Integer) As String
    Dim BaseValue As Integer = Convert.ToInt32(("A").Chars(0)) - 1
    Dim lsReturn As String = String.Empty

    If (aiColNumber > 26) Then
        lsReturn = GetExcelColumnName(Convert.ToInt32((Format(aiColNumber / 26, "0.0").Split("."))(0)))
    End If

    GetExcelColumnName = lsReturn + Convert.ToChar(BaseValue + (aiColNumber Mod 26))
End Function
0
ответ дан Manuel 12 September 2015 в 08:39
поделиться

Если Вы будете желать сослаться на ячейку progmatically тогда, то Вы получите намного больше читаемого кода при использовании метода Ячеек листа. Это берет строку и индекс столбца вместо традиционной ссылки на ячейку. Это очень похоже на метод Смещения.

0
ответ дан pipTheGeek 12 September 2015 в 08:39
поделиться
int nCol = 127;
string sChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol >= 26)
{
    int nChar = nCol % 26;
    nCol = (nCol - nChar) / 26;
    // You could do some trick with using nChar as offset from 'A', but I am lazy to do it right now.
    sCol = sChars[nChar] + sCol;
}
sCol = sChars[nCol] + sCol;

Обновление : комментарий Peter является правильным. Это - то, что я получаю для записи кода в браузере.:-) Мое решение не компилировало, это пропускало крайнюю левую букву, и это создавало строку в обратном порядке - все теперь зафиксированные.

Ошибки в стороне, алгоритм в основном преобразовывает число из основы 10 для базирования 26.

Обновление 2 : Joel Coehoorn прав - код выше возвратит AB для 27. Если бы это была реальная основа 26 чисел, то AA был бы равен A и следующему числу после того, как Z был бы BA.

int nCol = 127;
string sChars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol > 26)
{
    int nChar = nCol % 26;
    if (nChar == 0)
        nChar = 26;
    nCol = (nCol - nChar) / 26;
    sCol = sChars[nChar] + sCol;
}
if (nCol != 0)
    sCol = sChars[nCol] + sCol;
10
ответ дан 4 revs 12 September 2015 в 08:39
поделиться

Легкий с рекурсией.

public static string GetStandardExcelColumnName(int columnNumberOneBased)
{
  int baseValue = Convert.ToInt32('A');
  int columnNumberZeroBased = columnNumberOneBased - 1;

  string ret = "";

  if (columnNumberOneBased > 26)
  {
    ret = GetStandardExcelColumnName(columnNumberZeroBased / 26) ;
  }

  return ret + Convert.ToChar(baseValue + (columnNumberZeroBased % 26) );
}
10
ответ дан Peter 12 September 2015 в 08:39
поделиться
private String getColumn(int c) {
    String s = "";
    do {
        s = (char)('A' + (c % 26)) + s;
        c /= 26;
    } while (c-- > 0);
    return s;
}

не точно базируются 26, в системе существует № 0. Если бы было, 'Z' сопровождался бы 'BA' не 'AA'.

3
ответ дан rubberduckie 12 September 2015 в 08:39
поделиться

Извините, это - Python вместо C#, но по крайней мере результаты корректны:

def ColIdxToXlName(idx):
    if idx < 1:
        raise ValueError("Index is too small")
    result = ""
    while True:
        if idx > 26:
            idx, r = divmod(idx - 1, 26)
            result = chr(r + ord('A')) + result
        else:
            return chr(idx + ord('A') - 1) + result


for i in xrange(1, 1024):
    print "%4d : %s" % (i, ColIdxToXlName(i))
19
ответ дан RoMa 12 September 2015 в 08:39
поделиться

Уточнение исходного решения ( в C #):

public static class ExcelHelper
{
    private static Dictionary<UInt16, String> l_DictionaryOfColumns;

    public static ExcelHelper() {
        l_DictionaryOfColumns = new Dictionary<ushort, string>(256);
    }

    public static String GetExcelColumnName(UInt16 l_Column)
    {
        UInt16 l_ColumnCopy = l_Column;
        String l_Chars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String l_rVal = "";
        UInt16 l_Char;


        if (l_DictionaryOfColumns.ContainsKey(l_Column) == true)
        {
            l_rVal = l_DictionaryOfColumns[l_Column];
        }
        else
        {
            while (l_ColumnCopy > 26)
            {
                l_Char = l_ColumnCopy % 26;
                if (l_Char == 0)
                    l_Char = 26;

                l_ColumnCopy = (l_ColumnCopy - l_Char) / 26;
                l_rVal = l_Chars[l_Char] + l_rVal;
            }
            if (l_ColumnCopy != 0)
                l_rVal = l_Chars[l_ColumnCopy] + l_rVal;

            l_DictionaryOfColumns.ContainsKey(l_Column) = l_rVal;
        }

        return l_rVal;
    }
}
2
ответ дан 22 November 2019 в 23:05
поделиться

Вот версия Actionscript:

private var columnNumbers:Array = ['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'];

    private function getExcelColumnName(columnNumber:int) : String{
        var dividend:int = columnNumber;
        var columnName:String = "";
        var modulo:int;

        while (dividend > 0)
        {
            modulo = (dividend - 1) % 26;
            columnName = columnNumbers[modulo] + columnName;
            dividend = int((dividend - modulo) / 26);
        } 

        return columnName;
    }
2
ответ дан 22 November 2019 в 23:05
поделиться

Я обнаружил ошибку в своем первом посте, поэтому решил сесть и посчитать. Я обнаружил, что система счисления, используемая для идентификации столбцов Excel, не является системой с основанием 26, как писал другой человек. Рассмотрим следующее в базе 10. Вы также можете сделать это с буквами алфавита.

Пробел: ......................... S1, S2, S3: S1, S2, S3
.................................... 0, 00, 000: .. A, AA, AAA
.................................... 1, 01, 001: .. B, AB, AAB
....................................…,…,…: ..…,…,…
.................................... 9, 99, 999: .. Z, ZZ, ZZZ
Всего состояний в пространстве: 10, 100, 1000: 26, 676, 17576
Общее количество состояний: ............... 1110 ................ 18278

Excel пронумеровывает столбцы в отдельных алфавитных пространствах, используя основание 26. .Вы можете видеть, что в целом прогрессия в пространстве состояний равна a, a ^ 2, a ^ 3,… для некоторой базы a, а общее количество состояний равно a + a ^ 2 + a ^ 3 +….

Предположим, вы хотите найти общее количество состояний A в первых N пробелах. Формула для этого: A = (a) (a ^ N - 1) / (a-1). Это важно, потому что нам нужно найти пространство N, которое соответствует нашему индексу K. Если я хочу выяснить, где находится K в системе счисления, мне нужно заменить A на K и решить для N. Решение: N = log { основание a} (A (a-1) / a +1). Если я использую пример a = 10 и K = 192, я знаю, что N = 2,23804…. Это говорит мне, что K находится в начале третьего промежутка, так как он немного больше двух.

Следующим шагом будет определение того, как далеко мы находимся в текущем пространстве. Чтобы найти это, вычтите из K значение A, полученное с использованием минимального значения N. В этом примере минимальное значение N равно двум. Итак, A = (10) (10 ^ 2-1) / (10-1) = 110, как и ожидалось, когда вы объединяете состояния первых двух пробелов. Это необходимо вычесть из K, потому что эти первые 110 состояний уже были учтены в первых двух пространствах. Остается 82 государства. Итак, в этой системе счисления 192 в базе 10 представлены как 082.

Код C # с нулевым базовым индексом -

    private string ExcelColumnIndexToName(int Index)
    {
        string range = string.Empty;
        if (Index < 0 ) return range;
        int a = 26;
        int x = (int)Math.Floor(Math.Log((Index) * (a - 1) / a + 1, a));
        Index -= (int)(Math.Pow(a, x) - 1) * a / (a - 1);
        for (int i = x+1; Index + i > 0; i--)
        {
            range = ((char)(65 + Index % a)).ToString() + range;
            Index /= a;
        }
        return range;
    }

// Старая статья

Решение в C # с отсчетом от нуля.

    private string ExcelColumnIndexToName(int Index)
    {
        string range = "";
        if (Index < 0 ) return range;
        for(int i=1;Index + i > 0;i=0)
        {
            range = ((char)(65 + Index % 26)).ToString() + range;
            Index /= 26;
        }
        if (range.Length > 1) range = ((char)((int)range[0] - 1)).ToString() + range.Substring(1);
        return range;
    }
13
ответ дан 22 November 2019 в 23:05
поделиться

Если вам нужна просто формула для ячейки без кода, вот формула для нее:

IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))
4
ответ дан 22 November 2019 в 23:05
поделиться

Вот мое решение в python

import math

num = 3500
row_number = str(math.ceil(num / 702))
letters = ''
num = num - 702 * math.floor(num / 702)
while num:
    mod = (num - 1) % 26
    letters += chr(mod + 65)
    num = (num - 1) // 26
result = row_number + ("".join(reversed(letters)))
print(result)

0
ответ дан 22 November 2019 в 23:05
поделиться

Использование этого в VB.Net 2005:

Private Function ColumnName(ByVal ColumnIndex As Integer) As String

   Dim Name As String = ""

   Name = (New Microsoft.Office.Interop.Owc11.Spreadsheet).Columns.Item(ColumnIndex).Address(False, False, Microsoft.Office.Interop.Owc11.XlReferenceStyle.xlA1)
   Name = Split(Name, ":")(0)

   Return Name

End Function
0
ответ дан 22 November 2019 в 23:05
поделиться

Другое решение:

private void Foo()
{
   l_ExcelApp = new Excel.ApplicationClass();
   l_ExcelApp.ReferenceStyle = Excel.XlReferenceStyle.xlR1C1;
   // ... now reference by R[row]C[column], Ex. A1 <==> R1C1, C6 <==> R3C6, ...
}

подробнее см. здесь - Ссылки на ячейки в Excel для всех! Автор: Dr Nitin Paranjape

0
ответ дан 22 November 2019 в 23:05
поделиться
public static string ConvertToAlphaColumnReferenceFromInteger(int columnReference)
    {
        int baseValue = ((int)('A')) - 1 ;
        string lsReturn = String.Empty; 

        if (columnReference > 26) 
        {
            lsReturn = ConvertToAlphaColumnReferenceFromInteger(Convert.ToInt32(Convert.ToDouble(columnReference / 26).ToString().Split('.')[0]));
        } 

        return lsReturn + Convert.ToChar(baseValue + (columnReference % 26));            
    }
0
ответ дан 22 November 2019 в 23:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: