varias una sacar posicion porcentaje para obtener numero formato fila convertir como columna celdas celda c# excel

c# - una - porcentaje en excel formula



Cómo convertir un número de columna(por ejemplo, 127) en una columna de Excel(por ejemplo, AA) (30)

¿Cómo convertir un número a un nombre de columna de Excel en C # sin usar la automatización para obtener el valor directamente desde Excel?

Excel 2007 tiene un rango posible de 1 a 16384, que es el número de columnas que admite. Los valores resultantes deben estar en forma de nombres de columnas de Excel, por ejemplo, A, AA, AAA, etc.


..Y convertido a PHP:

function GetExcelColumnName($columnNumber) { $columnName = ''''; while ($columnNumber > 0) { $modulo = ($columnNumber - 1) % 26; $columnName = chr(65 + $modulo) . $columnName; $columnNumber = (int)(($columnNumber - $modulo) / 26); } return $columnName; }


Aquí está mi súper implementación tardía en PHP. Esta es recursiva. Lo escribí justo antes de encontrar esta publicación. Quería ver si otros ya habían resuelto este problema ...

public function GetColumn($intNumber, $strCol = null) { if ($intNumber > 0) { $intRem = ($intNumber - 1) % 26; $strCol = $this->GetColumn(intval(($intNumber - $intRem) / 26), sprintf(''%s%s'', chr(65 + $intRem), $strCol)); } return $strCol; }


Aquí hay una versión de 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; }


Así es como lo hago:

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


Descubrí un error en mi primera publicación, así que decidí sentarme y hacer los cálculos. Lo que descubrí es que el sistema numérico utilizado para identificar las columnas de Excel no es un sistema base 26, como lo publicó otra persona. Considere lo siguiente en la base 10. También puede hacer esto con las letras del alfabeto.

Espacio: ......................... S1, S2, S3: S1, S2, S3
.................................... 0, 00, 000: .. A, AA, AAA
.................................... 1, 01, 001: .. B, AB, AAB
....................................…,…,…: ..…,…,…
.................................... 9, 99, 999: .. Z, ZZ, ZZZ
Total de estados en el espacio: 10, 100, 1000: 26, 676, 17576
Total de Estados: ............... 1110 ................ 18278

Excel numera columnas en los espacios alfabéticos individuales usando la base 26. Puedes ver que, en general, la progresión del espacio de estado es a, a ^ 2, a ^ 3,… para alguna base a, y el número total de estados es a + a ^ 2 + a ^ 3 +….

Supongamos que desea encontrar el número total de estados A en los primeros N espacios. La fórmula para hacerlo es A = (a) (a ^ N - 1) / (a-1). Esto es importante porque necesitamos encontrar el espacio N que corresponde a nuestro índice K. Si quiero averiguar dónde se encuentra K en el sistema numérico, necesito reemplazar A por K y resolver para N. La solución es N = log { base a} (A (a-1) / a +1). Si uso el ejemplo de a = 10 y K = 192, sé que N = 2.23804…. Esto me dice que K se encuentra al comienzo del tercer espacio, ya que es un poco mayor que dos.

El siguiente paso es encontrar exactamente qué tan lejos estamos en el espacio actual. Para encontrar esto, reste de K la A generada usando el piso de N. En este ejemplo, el piso de N es dos. Entonces, A = (10) (10 ^ 2 - 1) / (10-1) = 110, como se espera cuando se combinan los estados de los dos primeros espacios. Esto debe restarse de K porque estos primeros 110 estados ya se habrían contabilizado en los dos primeros espacios. Esto nos deja con 82 estados. Entonces, en este sistema numérico, la representación de 192 en la base 10 es 082.

El código C # que usa un índice base de cero es

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

// Old Post

Una solución basada en cero en 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; }


Después de ver todas las versiones suministradas aquí, decidí hacer una yo mismo, usando la recursión.

Aquí está mi versión vb.net:

Function CL(ByVal x As Integer) As String If x >= 1 And x <= 26 Then CL = Chr(x + 64) Else CL = CL((x - x Mod 26) / 26) & Chr((x Mod 26) + 1 + 64) End If End Function


En Delfos (Pascal):

function GetExcelColumnName(columnNumber: integer): string; var dividend, modulo: integer; begin Result := ''''; dividend := columnNumber; while dividend > 0 do begin modulo := (dividend - 1) mod 26; Result := Chr(65 + modulo) + Result; dividend := (dividend - modulo) div 26; end; end;


En Perl, para una entrada de 1 (A), 27 (AA), etc.

sub excel_colname { my ($idx) = @_; # one-based column number --$idx; # zero-based column index my $name = ""; while ($idx >= 0) { $name .= chr(ord("A") + ($idx % 26)); $idx = int($idx / 26) - 1; } return scalar reverse $name; }


Es posible que necesite conversión en ambos sentidos, por ejemplo, desde la dirección de la columna de Excel como AAZ a entero y desde cualquier entero a Excel. Los dos métodos a continuación harán exactamente eso. Asume que la indexación basada en 1, el primer elemento de sus "arreglos" es el número de elemento 1. No hay límites en el tamaño aquí, por lo que puede usar direcciones como ERROR y ese sería el número de columna 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; }


Esta es la pregunta que todos los demás, así como la redirección de Google, así que estoy publicando esto aquí.

Muchas de estas respuestas son correctas pero demasiado complicadas para situaciones simples, como cuando no tiene más de 26 columnas. Si tiene alguna duda sobre si puede ingresar columnas de caracteres dobles, ignore esta respuesta, pero si está seguro de que no lo hará, entonces podría hacerlo tan simple como esto en 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); }

Diablos, si está seguro de lo que está pasando, podría incluso eliminar la validación y usar esta línea:

(char)(''A'' + index)

Esto será muy similar en muchos idiomas para que pueda adaptarlo según sea necesario.

Nuevamente, use esto solo si está 100% seguro de que no tendrá más de 26 columnas .


Esta es una versión de javascript según el código de Graham.

function (columnNumber) { var dividend = columnNumber; var columnName = ""; var modulo; while (dividend > 0) { modulo = (dividend - 1) % 26; columnName = String.fromCharCode(65 + modulo) + columnName; dividend = parseInt((dividend - modulo) / 26); } return columnName; };


Esta respuesta está en javaScript:

function getCharFromNumber(columnNumber){ var dividend = columnNumber; var columnName = ""; var modulo; while (dividend > 0) { modulo = (dividend - 1) % 26; columnName = String.fromCharCode(65 + modulo).toString() + columnName; dividend = parseInt((dividend - modulo) / 26); } return columnName; }


Estos mis códigos para convertir un número específico (índice comienza desde 1) a la columna de Excel.

public static string NumberToExcelColumn(uint number) { uint originalNumber = number; uint numChars = 1; while (Math.Pow(26, numChars) < number) { numChars++; if (Math.Pow(26, numChars) + 26 >= number) { break; } } string toRet = ""; uint lastValue = 0; do { number -= lastValue; double powerVal = Math.Pow(26, numChars - 1); byte thisCharIdx = (byte)Math.Truncate((columnNumber - 1) / powerVal); lastValue = (int)powerVal * thisCharIdx; if (numChars - 2 >= 0) { double powerVal_next = Math.Pow(26, numChars - 2); byte thisCharIdx_next = (byte)Math.Truncate((columnNumber - lastValue - 1) / powerVal_next); int lastValue_next = (int)Math.Pow(26, numChars - 2) * thisCharIdx_next; if (thisCharIdx_next == 0 && lastValue_next == 0 && powerVal_next == 26) { thisCharIdx--; lastValue = (int)powerVal * thisCharIdx; } } toRet += (char)((byte)''A'' + thisCharIdx + ((numChars > 1) ? -1 : 0)); numChars--; } while (numChars > 0); return toRet; }

Mi prueba de unidad:

[TestMethod] public void Test() { Assert.AreEqual("A", NumberToExcelColumn(1)); Assert.AreEqual("Z", NumberToExcelColumn(26)); Assert.AreEqual("AA", NumberToExcelColumn(27)); Assert.AreEqual("AO", NumberToExcelColumn(41)); Assert.AreEqual("AZ", NumberToExcelColumn(52)); Assert.AreEqual("BA", NumberToExcelColumn(53)); Assert.AreEqual("ZZ", NumberToExcelColumn(702)); Assert.AreEqual("AAA", NumberToExcelColumn(703)); Assert.AreEqual("ABC", NumberToExcelColumn(731)); Assert.AreEqual("ACQ", NumberToExcelColumn(771)); Assert.AreEqual("AYZ", NumberToExcelColumn(1352)); Assert.AreEqual("AZA", NumberToExcelColumn(1353)); Assert.AreEqual("AZB", NumberToExcelColumn(1354)); Assert.AreEqual("BAA", NumberToExcelColumn(1379)); Assert.AreEqual("CNU", NumberToExcelColumn(2413)); Assert.AreEqual("GCM", NumberToExcelColumn(4823)); Assert.AreEqual("MSR", NumberToExcelColumn(9300)); Assert.AreEqual("OMB", NumberToExcelColumn(10480)); Assert.AreEqual("ULV", NumberToExcelColumn(14530)); Assert.AreEqual("XFD", NumberToExcelColumn(16384)); }


Estoy tratando de hacer lo mismo en Java ... He escrito el siguiente código:

private String getExcelColumnName(int columnNumber) { int dividend = columnNumber; String columnName = ""; int modulo; while (dividend > 0) { modulo = (dividend - 1) % 26; char val = Character.valueOf((char)(65 + modulo)); columnName += val; dividend = (int)((dividend - modulo) / 26); } return columnName; }

Ahora, una vez que lo ejecuté con columnNumber = 29, me da el resultado = "CA" (en lugar de "AC") ¿Algún comentario sobre lo que me falta? Sé que puedo revertirlo con StringBuilder ... Pero mirando la respuesta de Graham, estoy un poco confundido ...


Estoy usando este en VB.NET 2003 y funciona bien ...

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


La misma implementación en Java.

public String getExcelColumnName (int columnNumber) { int dividend = columnNumber; int i; String columnName = ""; int modulo; while (dividend > 0) { modulo = (dividend - 1) % 26; i = 65 + modulo; columnName = new Character((char)i).toString() + columnName; dividend = (int)((dividend - modulo) / 26); } return columnName; }


Lo sentimos, esto es Python en lugar de C #, pero al menos los resultados son correctos:

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


Lo sentimos, esto es Python en lugar de C #, pero al menos los resultados son correctos:

def excel_column_number_to_name(column_number): output = "" index = column_number-1 while index >= 0: character = chr((index%26)+ord(''A'')) output = output + character index = index/26 - 1 return output[::-1] for i in xrange(1, 1024): print "%4d : %s" % (i, excel_column_number_to_name(i))

Pasaron estos casos de prueba:

  • Número de columna: 494286 => ABCDZ
  • Número de columna: 27 => AA
  • Número de columna: 52 => AZ

Me sorprende que todas las soluciones contengan iteraciones o recursiones.

Aquí está mi solución que se ejecuta en tiempo constante (sin bucles). Esta solución funciona para todas las posibles columnas de Excel y comprueba que la entrada se puede convertir en una columna de Excel. Las columnas posibles están en el rango [A, XFD] o [1, 16384]. (Esto depende de su versión de Excel)

private static string Turn(uint col) { if (col < 1 || col > 16384) //Excel columns are one-based (one = ''A'') throw new ArgumentException("col must be >= 1 and <= 16384"); if (col <= 26) //one character return ((char)(col + ''A'' - 1)).ToString(); else if (col <= 702) //two characters { char firstChar = (char)((int)((col - 1) / 26) + ''A'' - 1); char secondChar = (char)(col % 26 + ''A'' - 1); if (secondChar == ''@'') //Excel is one-based, but modulo operations are zero-based secondChar = ''Z''; //convert one-based to zero-based return string.Format("{0}{1}", firstChar, secondChar); } else //three characters { char firstChar = (char)((int)((col - 1) / 702) + ''A'' - 1); char secondChar = (char)((col - 1) / 26 % 26 + ''A'' - 1); char thirdChar = (char)(col % 26 + ''A'' - 1); if (thirdChar == ''@'') //Excel is one-based, but modulo operations are zero-based thirdChar = ''Z''; //convert one-based to zero-based return string.Format("{0}{1}{2}", firstChar, secondChar, thirdChar); } }


Otra forma de VBA

Public Function GetColumnName(TargetCell As Range) As String GetColumnName = Split(CStr(TargetCell.Address), "$")(1) End Function


Quería incluir mi clase estática que uso, para interoperar entre col index y col Label. Utilizo una respuesta aceptada modificada para mi Método ColumnLabel

public static class Extensions { public static string ColumnLabel(this int col) { var dividend = col; var columnLabel = string.Empty; int modulo; while (dividend > 0) { modulo = (dividend - 1) % 26; columnLabel = Convert.ToChar(65 + modulo).ToString() + columnLabel; dividend = (int)((dividend - modulo) / 26); } return columnLabel; } public static int ColumnIndex(this string colLabel) { // "AD" (1 * 26^1) + (4 * 26^0) ... var colIndex = 0; for(int ind = 0, pow = colLabel.Count()-1; ind < colLabel.Count(); ++ind, --pow) { var cVal = Convert.ToInt32(colLabel[ind]) - 64; //col A is index 1 colIndex += cVal * ((int)Math.Pow(26, pow)); } return colIndex; } }

Usa esto como ...

30.ColumnLabel(); // "AD" "AD".ColumnIndex(); // 30


Refinando la solución original (en 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; } }


Si alguien necesita hacer esto en Excel sin VBA, aquí hay una manera:

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

donde colNum es el número de columna

Y en 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


Si solo lo quieres para una fórmula de celda sin código, aquí hay una fórmula para ella:

IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))


Simplemente lanzar una implementación simple de C # de dos líneas usando la recursión, porque todas las respuestas aquí parecen mucho más complicadas de lo necesario.

/// <summary> /// Gets the column letter(s) corresponding to the given column number. /// </summary> /// <param name="column">The one-based column index. Must be greater than zero.</param> /// <returns>The desired column letter, or an empty string if the column number was invalid.</returns> public static string GetColumnLetter(int column) { if (column < 1) return String.Empty; return GetColumnLetter((column - 1) / 26) + (char)(''A'' + (column - 1) % 26); }


Un poco tarde para el juego, pero aquí está el código que uso (en C #):

private static readonly string _Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; public static int ColumnNameParse(string value) { // assumes value.Length is [1,3] // assumes value is uppercase var digits = value.PadLeft(3).Select(x => _Alphabet.IndexOf(x)); return digits.Aggregate(0, (current, index) => (current * 26) + (index + 1)); }


Fácil con la recursión.

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


Solución de JavaScript

/** * Calculate the column letter abbreviation from a 1 based index * @param {Number} value * @returns {string} */ getColumnFromIndex = function (value) { var base = ''ABCDEFGHIJKLMNOPQRSTUVWXYZ''.split(''''); var remainder, result = ""; do { remainder = value % 26; result = base[(remainder || 26) - 1] + result; value = Math.floor(value / 26); } while (value > 0); return result; };


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;

Actualización : el comentario de Peter es correcto. Eso es lo que obtengo por escribir código en el navegador. :-) Mi solución no estaba compilando, faltaba la letra que estaba más a la izquierda y estaba construyendo la cadena en orden inverso, todo ahora arreglado.

Dejando de lado los errores, el algoritmo básicamente convierte un número de la base 10 a la base 26.

Actualización 2 : Joel Coehoorn tiene razón: el código anterior devolverá AB para 27. Si era un número real de base 26, AA sería igual a A y el siguiente número después de Z sería 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;


private String getColumn(int c) { String s = ""; do { s = (char)(''A'' + (c % 26)) + s; c /= 26; } while (c-- > 0); return s; }

No es exactamente la base 26, no hay 0 en el sistema. Si existiera, ''Z'' sería seguido por ''BA'' no por ''AA''.