Column No to Column Letter in Excel/VSTO using C# - c#

How to find column's name or header?
For example if i select column 5 in excel means i want the result as "E".
How to get the alphabet or letter corresponding to column no.
Please help me with the code

public static string GetColumnName(int columnNumber)
{
const string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string columnName = "";
while (columnNumber > 0)
{
columnName = letters[(columnNumber - 1) % 26] + columnName;
columnNumber = (columnNumber - 1) / 26;
}
return columnName;
}

What about using Application.ActiveCell.get_Address(true, true, Excel.AlReferenceStyle.xlA1, missing, missing) and then parse the result string or use a RegEx to get the column heading?
I simply used:
string location = Application.ActiveCell.get_Address(true, true, Excel.AlReferenceStyle.xlA1, missing, missing);
string tokens = x.Split("$".ToCharArray());
MessageBox.Show(String.Format("Column {0}", result[0]));

public static long GetColumnNumber(string columnName)
{
int letterPos = 0;
long columnNumber = 0;
for (int placeHolder = columnName.Length - 1; placeHolder >= 0; placeHolder--)
{
int currentSum = 1;
for (int multiplier = 0; multiplier < placeHolder; multiplier++)
currentSum *= 26;
int letterValue = (int) columnName[letterPos];
currentSum *= letterValue - 64;
columnNumber += currentSum;
if (letterPos != columnName.Length)
letterPos++;
//Console.WriteLine(((int)columnName[i]-64) + " = " + columnName[i]);
}
return columnNumber;
}

The following is a complete method which gives you the corresponding alphabet for an integer value that is passed.
private String Number2String(int number, bool isCaps)
{
int number1 = number / 27;
int number2 = number - (number1 * 26);
if (number2 > 26)
{
number1 = number1 + 1;
number2 = number - (number1 * 26);
}
Char a = (Char)((isCaps ? 65 : 97) + (number1 - 1));
Char b = (Char)((isCaps ? 65 : 97) + (number2 - 1));
Char c = (Char)((isCaps ? 65 : 97) + (number - 1));
string d = String.Concat(a, b);
if (number <= 26)
return c.ToString();
else
return d;
}

I use these two:
public string GetExcelColumn(int index)
{
int quotient = index / 26;
if (quotient > 0)
return GetExcelColumn(quotient - 1) + (char)((int)'A' + (index % 26));
else
return "" + (char)((int)'A' + index);
}
static IEnumerable<string> GetExcelColumns()
{
var alphabet = new string[]{""}.Union(from c in Enumerable.Range((int)'A', 26) select Convert.ToString((char)c));
return from c1 in alphabet
from c2 in alphabet
from c3 in alphabet.Skip(1) // c3 is never empty
where c1 == string.Empty || c2 != string.Empty // only allow c2 to be empty if c1 is also empty
select c1 + c2 + c3;
}

This works well in VBA by using a double replace, where R is a Single Cell Excel Range:
ColumnLetter = Replace(Replace(R.AddressLocal(ReferenceStyle:=1), "$", vbNullString), R.Row, vbNullString)
It is based on the equivalent idea for use on a Worksheet. In a Cell Formula use this, it is even shorter:
=SUBSTITUTE(ADDRESS(1,COLUMN(M1),4),1,"")
This returns the letter M and works right up to Column XFD. The cell reference M1 can be any Range anywhere. The top left Column is returned for Ranges or more than one cell.
It gets the ADDRESS of the first Cell in the Column and then removes the trailing 1 by substituting a NullString for it. (The 4 in the ADDRESS makes sure that the Address is returned as a Relative Address, i.e. one without and $ signs in it.)
Thanks to barry houdini who set me off on the quest for a good answer to this.

Related

enumerating over the alphabet from 'a' to 'zzz'

I'm wondering if it is possible to enumerate over the alphabet from 'a' to 'zzz'?
For example I have a cave system that contains a maximum of 1000 caves and I would like to assign a char value to each of them.
1 = a, 2 = b, 3 = c ... 27 = aa etc
What would be the best way to go about doing this if it is possible?
void Main()
{
foreach (string word in EnumerateCaveNames())
Console.WriteLine(word);
}
IEnumerable<string> EnumerateCaveNames()
{
for (int i = 0; i < 26 * 26 * 26; ++i)
{
yield return BuildCaveName(i);
}
}
string BuildCaveName(int caveNum)
{
string name = (GetLetterFromNumber(caveNum / (26 * 26)) + GetLetterFromNumber((caveNum / 26) % 26) + GetLetterFromNumber(caveNum % 26)).TrimStart('a');
if (name == "")
name = "a";
return name;
}
string GetLetterFromNumber(int num)
{
return "" + (char)('a' + num);
}
It's like a converter for excel columns :
How to convert a column number (eg. 127) into an excel column (eg. AA)
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;
}

Creating a simple equation calculator with C#

So this is a bit of homework I have. I have to create a calculator application that asks for user input then calculates it. The input must be in an equation format. For example: " x = 3 + 8 ", " x = 6 - 3 " or x = " 6 - 3 * 9 ".
My approach to this problem is to first break down the string user input and store it into an array of char:
private char[] userInput;
string input = Console.ReadLine();
input = input.Replace(" " ,"");
userInput = input.ToCharArray();
At this point, userInput will contain all char from input. Next, I look for the variable of equation by looping through the array, this should give me the first alphabet character it found:
char var = 'x';
for (int i = 0; i < userInput.Length; i++)
{
char c = userInput[i];
if (Char.IsLetter(c)){
var = c;
break;
}
}
Next, I will break the equation up with variable one side and all of the number and operator in the other side, separated by '=', then add all number and operator to a new char array:
//get '=' position
int equalPos = 0;
for (int i = 0; i < userInput.Length; i++)
{
char c = userInput[i];
if (Char.IsSymbol(c))
{
if (c.Equals('='))
{
equalPos = i;
break;
}
}
}
//add equation to new array
rightSide = new char[userInput.Length-equalPos];
int a = 0;
for (int i = equalPos + 1; i < userInput.Length; i++)
{
char c = userInput[i];
rightSide[a] = c;
a++;
}
At this point, the rightSide array will contain all of the number and operator as character. I can calculate this part by using System.Data.DataTable().Compute(). However, if I am not allowed to use any library, how could I implement this? The equation should only contain 1 variable(always appear on the left side of the equation), four basic operators (+-/*) and no parenthesis.
Your answer can be divided into two parts
First How to convert char array to a string type
Second How to convert a string to a executable code block
For the first part use this method:
char[] chars;
string s = new string(chars);
For the Second part IT IS TOO DIFFiCULT to find a way without any pre-written code to do so then you must use Microsoft.CSharp.CSharpCodeProvider to compile code on-the-fly. In particular, search for CompileAssemblyFromFile.
If you first split the string by the = operator you will get the right and left hand side. So on the right hand side of the equation, if the equation is 'x = 6 * 2 + 1', we have '6 * 2 + 1', so we can compute that and follow standard BIDMAS rules using a loop and switch:
i have removed all error checking, this solution is for when a user inputs a perfect equation in the form 'x = {equation}' or '{equation} = x'
Also to note, a string is a char[]
//get user input
Console.Write("Enter equation:");
string input = Console.ReadLine();
string[] splitInput = input.Split('=');
int index = char.IsLetter(splitInput[0].Replace(" ", "")[0]) ? 1 : 0;
string sideWithEquation = splitInput[index];
//Compute right hand side
string[] equation = sideWithEquation.Split(' ');
Using BIDMAS, and ignoring brackets and indices, we compute divison and multiplication first.
//compute for * and /
for (int i = 1; i < equation.Length - 1; i++)
{
string item = equation[i];
int num = 0;
switch (item)
{
case "*":
num = Convert.ToInt32(equation[i - 1]) * Convert.ToInt32(equation[i + 1]);
break;
case "/":
num = Convert.ToInt32(equation[i - 1]) / Convert.ToInt32(equation[i + 1]);
break;
}
if (num > 0)
{
equation[i - 1] = "";
equation[i] = "";
equation[i + 1] = num.ToString();
}
}
And then we comoute for addition and subtraction
//Now compute for + and -
equation = string.Join(" ", equation).Split(' ');
for (int i = 1; i < equation.Length - 1; i++)
{
string item = equation[i];
int num = 0;
switch (item)
{
case "+":
num = Convert.ToInt32(equation[i - 1]) + Convert.ToInt32(equation[i + 1]);
break;
case "-":
num = Convert.ToInt32(equation[i - 1]) - Convert.ToInt32(equation[i + 1]);
break;
}
if (num > 0)
{
equation[i - 1] = "";
equation[i] = "";
equation[i + 1] = num.ToString();
}
}
and then to display the value of x to the user again
string total = string.Join("", equation);
//display what x is
Console.WriteLine($"x = {int.Parse(total)}" );

Serial key generation xor string encryption

When I do an xor on a string I get special characters
private void btnEncryptDecrypt_Click(object sender, EventArgs e)
{
byte[] bytes = Encoding.UTF8.GetBytes(keyTextBox.Text);
textTextBox.Text = string.Empty;
foreach (byte i in bytes)
{
byte c = Convert.ToByte(i ^ Convert.ToByte(textBox1.Text));
textTextBox.Text = textTextBox.Text + Convert.ToChar(c);
}
}
62FA7AC4 1234567890 xor to !%QV VT#7&%$#"! /.'
I want to use it for serial key generation with only alphanumeric characters
I want to pass "62FA7AC4", a date and a number between 0 and 5000 and a few random dummy numbers
Input will be "62FA7AC4"+"2500"+"21/05/2018"
Output should be something like "5QBK-J4D1-8CF6-5MW2-78FZ-2FPL-4S6S-CTGB"
What am I doing Wrong?
Try working with numbers, not strings:
using System.Numerics;
...
// Let's use BigInteger for arbitrary long values
BigInteger left = BigInteger.Parse("62FA7AC4", NumberStyles.HexNumber);
BigInteger right = BigInteger.Parse("1234567890", NumberStyles.HexNumber);
string result = (left ^ right).ToString("X");
Console.Write(result);
So you have
1256AC0254
Edit: As far as I can see you want alphanumeric (i.e. Base 36 == 26 letters + 10 digits output). You can use the same approach: operate with integer(s), not string(s)
private static Random s_Random = new Random();
...
BigInteger value = BigInteger.Parse(
"0" + // we don't want negative values
"62FA7AC4" + // header
s_Random.Next(5001).ToString("0000") + // random in [0..5000] range
DateTime.Today.ToString("ddMMyyyy"), // Date like 21052018
NumberStyles.HexNumber);
Then do any xor (if you like):
value ^= some_secret_value;
Finally represent the value in base 36:
private static String ToBase36(BigInteger value) {
List<char> list = new List<char>();
for (int index = 0; value > 0; value /= 36, index++) {
if (index > 0 && index % 4 == 0)
list.Add('-');
BigInteger v = value % 36;
list.Add(v < 10 ? (char)('0' + v) : (char) ('A' + v - 10));
}
list.Reverse();
return string.Concat(list);
}
Test:
BigInteger value = BigInteger.Parse(
"0" +
"62FA7AC4" +
"2500" +
DateTime.Today.ToString("ddMMyyyy"),
NumberStyles.HexNumber);
string result = ToBase36(value);
Console.Write(result);
Outcome:
2443-WNC5-AVBB-M32W
Edit 2: To restore the original number
private static BigInteger FromBase36(string value) {
BigInteger result = 0;
BigInteger power = 1;
for (int i = value.Length - 1; i >= 0; --i) {
char item = value[i];
if (item >= '0' && item <= '9') {
result += power * (item - '0');
power *= 36;
}
else if (item >= 'A' && item <= 'Z') {
result += power * (item - 'A' + 10);
power *= 36;
}
else if (item >= 'a' && item <= 'z') {
result += power * (item - 'a' + 10);
power *= 36;
}
}
return result;
}
e.g.
BigInteger value = BigInteger.Parse(
"0" +
"62FA7AC4" +
"2500" +
DateTime.Today.ToString("ddMMyyyy"),
NumberStyles.HexNumber);
string result = ToBase36(value);
BigInteger back = FromBase36(result);
Console.WriteLine(string.Join(Environment.NewLine, value, result, back));
Outcome:
467412447575903165554712
2443-WNC5-AVBB-M32W
467412447575903165554712

How can I extract the places values of a number?

I'm working on a math game in the Unity game engine using C#, specifically a reusable component to teach the grid method for multiplication. For example, when given the numbers 34 and 13, it should generate a 3X3 grid (a header column and row for the multiplier and multiplicand place values and 2X2 for the number of places in the multiplier and multiplicand). Something that looks like this:
My issue is that I don't know the best way to extract the place values of the numbers (eg 34 -> 30 and 4). I was thinking of just converting it to a string, adding 0s to the higher place values based on its index, and converting it back to an int, but this seems like a bad solution. Is there a better way of doing this?
Note: I'll pretty much only be dealing with positive whole numbers, but the number of place values might vary.
Thanks to all who answered! Thought it might be helpful to post my Unity-specific solution that I constructed with all the replies:
List<int> GetPlaceValues(int num) {
List<int> placeValues = new List<int>();
while (num > 0) {
placeValues.Add(num % 10);
num /= 10;
}
for(int i = 0;i<placeValues.Count;i++) {
placeValues[i] *= (int)Mathf.Pow(10, i);
}
placeValues.Reverse();
return placeValues;
}
Take advantage of the way our number system works. Here's a basic example:
string test = "12034";
for (int i = 0; i < test.Length; ++i) {
int digit = test[test.Length - i - 1] - '0';
digit *= (int)Math.Pow(10, i);
Console.WriteLine("digit = " + digit);
}
Basically, it reads from the rightmost digit (assuming the input is an integer), and uses the convenient place value of the way our system works to calculate the meaning of the digit.
test.Length - i - 1 treats the rightmost as 0, and indexes positive to the left of there.
- '0' converts from the encoding value for '0' to an actual digit.
Play with the code
Perhaps you want something like this (ideone):
int n = 76302;
int mul = 1;
int cnt = 0;
int res[10];
while(n) {
res[cnt++] = (n % 10) * mul;
mul*=10;
cout << res[cnt-1] << " ";
n = n / 10;
}
output
2 0 300 6000 70000
My answer is incredibly crude, and could likely be improved by someone with better maths skills:
void Main()
{
GetMulGrid(34, 13).Dump();
}
int[,] GetMulGrid(int x, int y)
{
int[] GetPlaceValues(int num)
{
var numDigits = (int)Math.Floor(Math.Log10(num) + 1);
var digits = num.ToString().ToCharArray().Select(ch => Convert.ToInt32(ch.ToString())).ToArray();
var multiplied =
digits
.Select((d, i) =>
{
if (i != (numDigits - 1) && d == 0) d = 1;
return d * (int)Math.Pow(10, (numDigits - i) - 1);
})
.ToArray();
return multiplied;
}
var xComponents = GetPlaceValues(x);
var yComponents = GetPlaceValues(y);
var arr = new int[xComponents.Length + 1, yComponents.Length + 1];
for(var row = 0; row < yComponents.Length; row++)
{
for(var col = 0; col < xComponents.Length; col++)
{
arr[row + 1,col + 1] = xComponents[col] * yComponents[row];
if (row == 0)
{
arr[0, col + 1] = xComponents[col];
}
if (col == 0)
{
arr[row + 1, 0] = yComponents[row];
}
}
}
return arr;
}
For your example of 34 x 13 it produces:
And for 304 x 132 it produces:
It spits this out as an array, so how you consume and display the results will be up to you.
For two-digit numbers you can use modulo
int n = 34;
int x = n % 10; // 4
int y = n - x; // 30

How do I print my output from left to right?

Below codes run perfectly fine. But how to I print converted number in left to right manner. For example if I input 898989, it will give me the output DB7AD. How do I print
DB7AD to
D
B
7
A
D
Codes:
public static void Main()
{
int decimalNumber, quotient;
int i = 1, j, num = 0;
char [] hexadecimalNumber = new char[100];
char temp;
Console.WriteLine("Decimal to HexaDecimal conversion using Ascii code.\n");
Console.WriteLine("Input DECIMAL NUMBER(S) you want to convert to HEXADECIMAL(S):\t\n");
Console.Write("Decimal Numbers : \t");
decimalNumber = int.Parse(Console.ReadLine());
quotient = decimalNumber;
while (quotient != 0)
{
num = quotient % 16;
if (num < 10)
num = num + 48;
else
num = num + 55;
temp = Convert.ToChar(num);
hexadecimalNumber[i++] = temp;
quotient = quotient / 16;
}
Console.Write("HexaDecimal Numbers : \t");
for (j = i - 1; j > 0; j--)
Console.Write(hexadecimalNumber[j]);
Console.WriteLine();
Console.Read();
}
Since you are printing your number character-by-character, you need to modify this loop
for (j = i - 1; j > 0; j--) {
Console.Write(hexadecimalNumber[j]);
}
in such a way as to print zero tabs before the first digit, one tab before the second digit, two tabs before the third digit, and so on. You can do it by making a string tabs variable, and adding a "\t" to it after each iteration:
string tabs = "";
for (j = i - 1; j > 0; j--) {
Console.WriteLine(tabs + hexadecimalNumber[j]);
tabs += "\t";
}
Demo on ideone.

Categories