C# issue when calculating a reference - c#

I put together this little script whose goal is to calculate a reference according to the document type chosen in a form, and to concatenate a number that's auto-incremented. I am however getting this error when saving:
the string or binary data would be truncated
string typeDocAbbr = doc.GetStringValue("Document_type_Abbr");
string textRef = doc.GetStringValue("text_reference");
if (typeDocAbbr == "DIV")
returnValue = string.Format("{0}-{1}", typeDocAbbr, textRef);
if ((typeDocAbbr == "FIC") || (typeDocAbbr == "FTC") || (typeDocAbbr == "FDP"))
returnValue = string.Format("{0}-{1}", typeDocAbbr, textRef);
else
{
int chrono = 0;
string schrono = "";
if(string.IsNullOrEmpty(doc.GetStringValue("Reference")))
{
if (!string.IsNullOrEmpty(typeDocAbbr))
{
EDITOR.Documents.DataSource.ChronoManagerWrapper cmw =
new EDITOR.Documents.DataSource.ChronoManagerWrapper();
string Key = typeDocAbbr;
chrono = cmw.GetNewChrono("Process Studio", Key);
if (chrono < 10)
schrono = "0" + chrono.ToString();
else
schrono = chrono.ToString()};
}
}
returnValue = string.Format("{0}-{1}", typeDocAbbr, schrono);
}

This error :
the string or binary data would be truncated
is NOT on the code you shown. It is a SQL Server error.
It means that DB field is too small for the value you tried to insert.

Okay people, my bad.
I actually figured out where I went wrong. The returnValue of the script I shared went to feed a column the max size of which was 10 for some reason. However, as some of you so nicely pointed out to a beginner like me, the error was originating from the table, not the script, indicating that the value was too big for the column (that's what she said).
Thank you for some constructive criticism!

Related

How to compare a fixed value against multiple values and find if any one fails to match

I have a fixed int value - 1050. I have around 50 dynamic values that I want to compare with the fixed value. So I compare it in a for loop. I have a public variable which I set as ok or notok depending on result. But my problem is that the value of the public variable is always the last value that I compared. Example, If I have the 20th dynamic value as 1000, it should return notok, but the value of the variable is always the last compared value. How do I set the variable to notok even if one/multiple of the values of dynamic variable doesnt match with fixed variable? I also display the total number of notok values in a listbox.
Here is what I have:
string result;
for(int i = 0; i < dynamicvalue.count; i++)
{
if(dynamicvalue[i] != setvalue)
{
result = "notok";
listBox1.Items.Add(result);
}
else
{
result = "ok";
}
}
To have "notok" if theres at least one not matching, one way to do it in plain code:
string result = "ok";
for(int i=0; i<dynamicvalue.count; ++i)
{
if(dynamicvalue[i] != setvalue)
{
result = "notok";
break;
}
}
You can use .Any() from Linq,
Determines whether any element of a sequence exists or satisfies a
condition.
string result = dynamicvalue.Any(x => x == setValue) ? "Ok" : "Not Ok";
If you want to use for loop without a break statement, you are just increasing the time complexity of your code.
I will never recommend it, but if you want you can try the below code
string result = "Ok";
bool flag = true;
//This for loop will iterate for n times.
for(int i = 0; i < dynamicvalue.Count; i++)
{
if(dynamicvalue[i] != setvalue && flag)
{
result = "Not Ok";
flag = false; //flag will help us to execute this block of code only once.
}
}
Perhaps the most performant way to answer this would be to keep your numbers in a HashSet instead (make dynamicvalue a HashSet<int>), then it's:
dynamicvalue.Contains(setvalue) ? "ok" : "notok"
A HashSet can much more quickly answer "do you contain this value?" than a list/array can
By the discussion going on in the comments I'm thinking that you want to go through all the elements in dynamicvalue and check all if any of them are ok or notok. If that is the case, you should turn result into an array. You get the last compared result because each time the cycle loops, the string gets assigned a new value all over again so the previous value gets discarded.
Is this what you want to do? I wrote it in c++
int setvalue = 1050;
int notok = 0;
int dynamicvalue[5] = {1, 2, 3, 1050, 4}; //for example
string result[5];
for (int i = 0; i < sizeof(dynamicvalue); i++){
if (dynamicvalue[i] != setvalue){
result[i] = "notok";
notok++; //to keep track of notok
}
else{
result[i] = "ok";
}
}
Afterwards if you cycle through the result array you will see that all the values were saved. I find it simpler to have an int variable to know how many times the result was notok
You forgot to get the actual value within dynamicvalue: your test should be if (dynamicvalue[i] != setvalue).
EDIT: And add a break; after the result="ok"; instruction to break the loop, too.
EDIT 2: An above answer gives the corrected code using a break.
I found a solution to this by reading #deminalla 's answer.
I added two more integers to work as counters and after the for loop I compare the values of these integers to get the final result.
Here's what I did:
string result;
int okcounter = 0;
int notokcounter = 0;
for(int i = 0; i < dynamicvalue.count; i++)
{
if(dynamicvalue[i] != setvalue)
{
notokcounter ++;
listBox1.Items.Add(notokcounter);
}
else
{
okcounter++;;
}
}
if(notokcounter >=1)
{
result = "notok";
}
else if(okcounter == dynamicvalue.count)
{
result = "ok";
}

How to check if a number exists in a specified digit of an integer ( C# )

I want to generally verify if a number/character exists within a specified index of an int value.
Here is pseudocode of what I want
if (octet[1].Exists){
return true;
} else {
return false;
}
// receiving int octet = 103 will return true.
// receiving int octet = 7 will return false.
Is there a function that already does this, or do you have to make one on your own?
Convert to a string then check the length?
var str = octet.ToString();
return str.Length >= 1;
I don't know a function like this, but you can write your own.
In instance:
var func = (int octet, int index) => (octet / (int)(Math.Pow(10, index)) != 0);
I would suggest using a System.Linq binding for this. Here is an example:
octet.ToString().Contains(n);
Where n is the digit you're looking for in string or char form. Hope this helps!
Just parse the int to a string and check if the number you are looking is equal to expected position.
var number = 12345;
if(number.ToString().IndexOf('2') == 1)//check if the value 2 is on the second position of the array
{
Console.WriteLine("yes");
}

c# how to convert char to VirtualKeyCode?

I've been looking over here, but usually question is other way roud "how to convert virtualkey to char".
So I need to ask how to convert char into virtualkeycode?
I can perfectly fine work with F1, Ctrl etc., but can't figure out how to convert A to VK_A etc. in some convenient way.
I'm trying to let external configuration file hold some variables which then have to be used as virtualkeycodes in actual application.
I can recognize pairs like
Alt+F2, Shift+Control+F1 ... etc.
As those are just Enum 0-12 and then VirtualKeyCode.F1 + index
But I can't figure out those
Alt+F, Shift+Control+A ... etc.
I'm probably missing something very straightforward but unfortunately i can't see it.
Thanks
Edit:
Thanks to help from here I'm now able to convert "Ctrl+X" or "Shift-A" into VirtualKeyCode with this bit of code (still more like testing code)
public static void ParseKeys(string text)
{
Key key = 0;
Key mod = 0;
int current = 0;
string[] result;
string[] separators = new string[] { "+", "-" };
result = text.Split(separators, StringSplitOptions.RemoveEmptyEntries);
foreach (string entry in result)
{
if (entry.Trim() == Keys.Control.ToString() || entry.Trim() == "Ctrl")
mod = Key.LeftCtrl;
if (entry.Trim() == Keys.Alt.ToString())
mod = Key.LeftAlt;
if (entry.Trim() == Keys.Shift.ToString())
mod = Key.LeftShift;
if (entry.Trim() == Keys.LWin.ToString() && current != result.Length - 1)
mod = Key.LWin;
current++;
}
KeysConverter keyconverter = new KeysConverter();
key = (Key)keyconverter.ConvertFrom(result.GetValue(result.Length - 1));
var vmod = KeyInterop.VirtualKeyFromKey(mod);
System.Diagnostics.Trace.WriteLine((VirtualKeyCode)vmod + " = " + (VirtualKeyCode)key);
}
usage
ParseKeys("Alt+X");
I found out I would need to handle combinations like "Alt+Ctrl+X" or "Ctrl+X+Q" but indeed this code is for A+B combo. Can somebody please suggest some elegant solution to have at the end this:
VirtualKeyCode[] outsequence = { VirtualKeyCode.A , VirtualKeyCode.B, VirtualKeycode.C }
?
Thanks!

Advice on this method that works with chars

Recently I've been told to change one validation towards a database to a new database in a C# application. Instead of the old database I would be using the new one.
The problem is that I can't run the app. I need to publish it so the guys that uses it give me their feedback.
So I decided to share this part of the code that I added.
Not changed, but added. This is something new and a potential thing that can go wrong.
Hopefully someone with more experience will tell me how much my code sucks or if it looks OK.
Thing is... the old database has an int value in a column and the new one has a nvarchar(5).
So I made this to convert the old one in a new one.
string ConvertIDToReg(string kairosID)
{
double n;
if (!Double.TryParse(Convert.ToString(kairosID),
System.Globalization.NumberStyles.Any,
System.Globalization.NumberFormatInfo.InvariantInfo, out n))
{
return "0";
}
char[] regID = kairosID.ToCharArray();
if (regID.Length > 4)
{
return "0";
}
if (reg.Length == 3)
{
regID[4] = regID[3];
regID[3] = regID[2];
regID[2] = regID[1];
regID[1] = regID[0];
regID[0] = "0";
}
return regID.ToString();
}
This is how it should work:
The old ID is something like "1234" but the new one is a 5 char max ID with a 0 in the beginning like "01234" (if the 5th number is not occupied). So basically I want to be able to put a 0 in the beginning if there isn't a 5th number.
If the number exceeds the 5 digits I want to return a 0 as the whole string (this will be handled later)
If the number is not a number (i.e "123ABC") return a 0 all the same.
Should this compile or even work?
What about efficiency? This will run several times. Any help to make this faster will do.
No, this won't compile. You misspelled your second regID (forgot the 'ID'), and are assigning a string to a char at regID[0] = "0";
Change that and it will compile, then blow up when you run it, when regID.Length= 3, because you're trying to access index 3 and 4, which it clearly will not have.
This should do what you're wanting:
string ConvertIDToReg(string kairosID)
{
if (kairosID.Length > 4 || kairosID.Any(c => !char.IsDigit(c)))
return "0";
return kairosID.PadLeft(5, '0');
}
if it's longer than 4 characters or if any character is not a digit, return a zero as a string ("0"). Else return the ID padded to 5 digits. About as simple as i can make it I think. No need to parse it as an int even.
This code should work:
private string ConvertIntToChar(string numValue)
{
int result = 0;
if (int.TryParse(numValue, out result) == false || numValue.Length > 4)
{
return "0";
}
return numValue.PadLeft(5, '0');
}
If value is not of 4 characters then it will add number of "0" required to make the string length equal to 5.
If the string is always some form of an integer i would approach the problem as such. and you wanted to keep every thing else the same. the "D5" tells the ToString method to 0 pad the string so that it is always 5 digits but retains the same numerical value.
string ConvertIDToReg(string kairosID)
{
int id;
if (!Int32.TryParse(kairosID, out id) || id > 9999)
{
return "0";
}
return id.ToString("D5");
}

retrieving number value from datagridview C#

I am trying to retrieve a numerical value from datagridview. The data type for both the value in the table, and the variable (weeklyTotal), are integer. Also I am trying to cast it into integer. I looked through the whole website for similar problems, and yet none of the solutions were helpful. The error message that I am getting is “when casting form a number, the value must be less than infinity”. I went back to my table more than one time to make sure that I don’t have invalid value.
it's a runtime error and the IDE always point at this line
weeklyTotal += (int)dataGridView1.Rows[i].Cells[1].Value;
for (int i = 0; i < this.dataGridView1.Rows.Count; i++)
{
sdate = dataGridView1.Rows[i].Cells[2].Value.ToString();
ddate = dataGridView1.Rows[i].Cells[3].Value.ToString();
if ((weekFirstDay <= Convert.ToInt32(sdate) &&
Convert.ToInt32(sdate) <= (weekFirstDay + 7))||(weekFirstDay <= `Convert.ToInt32(ddate) &&`
Convert.ToInt32(ddate) <= (weekFirstDay + 7)))
{
dataGridView1.Rows[i].Selected = true;
dataGridView1.Rows[i].Visible = true;
weeklyTotal += (int)dataGridView1.Rows[i].Cells[1].Value;
//weeklyTotalString = dataGridView1.Rows[i].Cells[1].Value.ToString();
//weeklyTotal += Convert.ToInt32(weeklyTotalString);
}
else
That's because the following won't cast your cell value to the int type:
(int) dataGridView1.Rows[i].Cells[1].Value
You're just taking the string saying "hey compiler, please treat it as an int type", but it will still be a string type underneath. Use the Convert.ToInt32 method like you did earlier.
weeklyTotal += Convert.ToInt32(dataGridView1.Rows[i].Cells[1].Value);
int num = Convert.ToInt32(dgv.Rows[i].Cells["col_name"].Value);
You may be trying to to an (int) cast on a DBNull value. I'm assuming that you populating the datagridview with data from the database.
Try this:
if(dataGridView1.Rows[i].Cells[1].Value != DBNull.Value)
{
weeklyTotal += (int)dataGridView1.Rows[i].Cells[1].Value;
}

Categories