I am creating an indicator for NinjaTRader v8 using Drax.Line and Draw.Rectagle.
Draw.Line is ok:
Draw.Line(this, prefix + "Lower 3 " + tag, false, startl, lower3, endl, lower3, IsGlobal, template);
but when I use Draw.Rectangle:
Draw.Rectangle(this, prefix + "Previous Balanced Zone " + tag, startl, lower1, endl, upper1, IsGlobal, template);
I get an error message
Indicator 'AM_VWAP': Error on calling 'OnBarUpdate' method on bar 0: NinjaTrader.NinjaScript.DrawingTools.Rectangle endTime must be greater than the minimum Date but was 01/01/0001 00:00:00
I tried to change the datetime value, I put a "by hand" one (not calculated)
I displayed on the screen the value of the date time parameters they are ok.
I do not understand why this error message.
Related
I'm creating an app in C# that uses EConnect to import information into Great Plains. EConnect has it own set of exceptions which are really great to know if you are passing the app the wrong information. I want to display an error message if an EConnectException is thrown. My problem is the EConnect exception is very long so I want to extract a particular part from it.
The exception string look like the following example:
Microsoft.Dynamics.GP.eConnect.eConnectException: Sql procedure error codes returned:
Error Number = 714 Stored Procedure= taPMTransactionInsert Error Description = You can not enter a 1099 value (TEN99AMNT) > than the Purchase Amount (PRCHAMNT) minus the Trade Discount Amount (TRDISAMT)Node Identifier Parameters: taPMTransactionInsert
All I really want for my error messages is the Error Description part. Its easy enough to cut out the part before Error Description because that portion is always the same length. The Error Description can vary in length so thats where I'm having trouble figuring out how to extract it. In the end what I would want it the starting at Error Description and ending before Node Identifier Parameters (which always comes after the Error Description)
Here is how I catch my exception right now and cut off the first part of the error message. setStatusErrorLogs is just a function I use to display my errors to my app.
catch (eConnectException exc)
{
setStatusErrorLogs((exc.ToString()).Substring(85), xInvoiceNumber + ": ", "CreateInvoice");
}
Any ideas how I can extract this string?
Use string.IndexOf method
var error = exc.ToString();
var startIndex = error.IndexOf("Error Description = ") + "Error Description = ".Length;
var endIndex = error.LastIndexOf("Node Identifier Parameters:");
var desc = error.Substring(startIndex, endIndex - startIndex);
setStatusErrorLogs(desc, xInvoiceNumber + ": ", "CreateInvoice");
This approach is very error prone! If you are not sure about the exact format and content of the excetpion then you should do checks not to get junk data!
Use string.IndexOf to find the index of the string "Node Identifier". then use string.SubString to get everything between the 85th character and the index returned by IndexOf.
Here's a simple Regex that captures what you want:
.*Error Description(.*)Node Identifier.*
Here's code that uses this:
string text = "Error Number = 714 Stored Procedure= taPMTransactionInsert Error Description = You can not enter a 1099 value (TEN99AMNT) > than the Purchase Amount (PRCHAMNT) minus the Trade Discount Amount (TRDISAMT)Node Identifier Parameters: taPMTransactionInsert";
var desc = Regex.Replace(text, ".*Error Description(.*)Node Identifier.*", "$1");
Console.WriteLine(desc);
This regex uses greedy matching to ensure that if the description contains the phrase "Error Description" or "Node Identifier", it'll still match as you expect.
Test out the regex here
Find the index of Node identifier with String.IndexOf()
Solution would be like this
string exception = exc.ToString();
int nodeIndex = exception.IndexOf("Node identifier");
string errorDescription = exception.Substring(85, nodeIndex);
setStatusErrorLogs(errorDescription, xInvoiceNumber + ": ", "CreateInvoice");
This can be achieved like this:
var lookUpString = "Error Description =";
var lookUpStringEnd = "Node Identifier";
var stringToLookIn ="Microsoft.Dynamics.GP.eConnect.eConnectException: Sql procedure error codes returned: Error Number = 714 Stored Procedure= taPMTransactionInsert Error Description = You can not enter a 1099 value (TEN99AMNT) > than the Purchase Amount (PRCHAMNT) minus the Trade Discount Amount (TRDISAMT)Node Identifier Parameters: taPMTransactionInsert";
var indexOfLookUpString = stringToLookIn.IndexOf(lookUpString);
var indexOfLookUpStringEnd = stringToLookIn.IndexOf(lookUpStringEnd);
var stringWithLookUpStringIncluded= stringToLookIn.Substring(indexOfLookUpString,indexOfLookUpStringEnd-indexOfLookUpString);
var stringWithoutLookUpStringIncluded = stringToLookIn.Substring(indexOfLookUpString+lookUpString.Length,indexOfLookUpStringEnd -(indexOfLookUpString+lookUpString.Length));
Console.WriteLine(stringWithLookUpStringIncluded);
// output: Error Description = You can not enter a 1099 value (TEN99AMNT) > than the Purchase Amount (PRCHAMNT) minus the Trade Discount Amount (TRDISAMT)
Console.WriteLine(stringWithoutLookUpStringIncluded);
//output: You can not enter a 1099 value (TEN99AMNT) > than the Purchase Amount (PRCHAMNT) minus the Trade Discount Amount (TRDISAMT)
Read more about String.Substring and String.IndexOf
I'm trying to display in a graph (Winforms/C#) the total amount from one column vs unit of time (in this case month) - so it would be a amount vs time graph. The problem is that the user would like the freedom of lets say - choosing the totals for January and June and compare them in a single graph (so the total for the month of January would be represented as a bar next to June's total's bar). I already capture the selected months (also, I have the graph control on the for) within a list but where I am really stuck is to build the mysql statement and its something like this
selectdataforGraph = "SELECT SUM(Amount_Net) AS Total FROM testingproject.incomeinformation WHERE date";
foreach (int month in selectedMonth) {
selectdataforGraph += "between '" + selected_year+ "-" + month +
"'-1 AND '" + selected_year + "-"+month+ "-31' AND";
}
I know it has some space missing and some quotation mark problems - already ran the query and I figured as much but I don't think the in-between would work because I don't know how to AND the next part of it so if a user picks May then August would be between 2007-5-01 and 2007-5-30 AND 2007-8-01 and 2007-8-30???
EDIT: didn't seem MySQL was your DB...
Definitely use a parameterized query! However... to fit in with what you have and so you can test it quickly...
I think I would use DATEPART rather than BETWEEN....
var selectdataforGraph = "SELECT SUM(Amount_Net) AS Total FROM testingproject.incomeinformation WHERE ";
var monthList = string.Join(",", selectedMonth);
selectdataforGraph += " YEAR(date) = " + selected_year;
selectdataforGraph += " AND MONTH(date) in (" + monthList + ")";
I have written a JS that should check that start date is less than end date. If not, alert should be thrown
The JS is written as;
function DateValidation(startDate, EndDate) {
debugger;
var stdate = startDate;
var enddate = EndDate;
if (stdate!= '' && enddate!='') {
if (stdate > enddate) {
alert('Start date cannot be greater than end date');
return false;
}
else {
return true;
}
}
}
This JS gets fired when i am clicking a button as "Show Report".
Problems that i am facing
JS doesn't validate the date correctly. What am i missing? i am passing date from the textbox
The JS doesn't fired up when clicking button for the first time. it fires when clicking the button second time
Plus, i have registered the JS as below;
btnShowReport.Attributes.Add("onclick", "return DateValidation('" + txtStartDate.Text + "', '" + txtEndDate.Text + "');");
Is the above code correct? What is the correct place to register the JS?
Please guide.. thanks!
You need to parse the string values to dates
if (startDate!= '' && EndDate!='') {
var stdate = Date.parse(startDate);
var enddate = Date.parse(EndDate);
if (stdate > enddate) {
alert('Start date cannot be greater than end date');
return false;
}
else
{
return true;
}
}
Without further code it's hard to tell why your button only fires the event on the second click. Is your button disabled to start with?
Use Date.parse. What you are doing is checking whether a string is greater than another string.
Also the script will take only whatever is there at the first time in txtStartDate.Text, txtEndDate.Text EVERY time the script runs.
Why? You have not correctly understood server side and client side execution.
This line in your code,
btnShowReport.Attributes.Add("onclick", "return DateValidation('" + txtStartDate.Text + "', '" + txtEndDate.Text + "');");
registers the script to the page passing the text in those text boxes.
You have assumed that each time the text changes in the text box, the method will take the new values and do the date calculation.
However your script would look something like this, assuming the two text boxes are empty when the page is loaded. You can verify this by checking the page source.
<inputid="btnShowReport" ... onclick="return DateValidation('','')>
Because JavaScript is run at client side, the server is not contacted each time to get the current values of those text boxes.
What you can do is pass the text boxes it self to the method. Something like
return DateValidation(txtStartDate.ClientID, txtEndDate.ClientID);
and from the method you can access it like shown below
function DateValidation(txtStartDate, txtEndDate) {
debugger;
var stdate = Date.parse(txtStartDate.value);
I think the problem is that you're not comparing dates - you have just declared them as vars without a type so they're essentially Strings.
Check out the Date.parse() method.
Adding to what the previous 2 guys have answered with, you have to parse the dates. You also need to validate that they are even dates. I use this library often when working with dates on the client side:
http://www.datejs.com/
The main problem is how you register the event. You are creating a string with code that contains string literals with the values, which means that you get the values from the textboxes at the time that you create the string, not at the time that the event is activated. You have to make a postback before the code is updated with the current values, that is why it doesn't work on the first click.
Create code that gets the values at the time of the click:
btnShowReport.Attributes.Add("onclick", "return DateValidation(document.getElementById('" + txtStartDate.ClientID + "').value, document.getElementById('" + txtEndDate.ClientID + "').value);");
Another possible problem is that the code doesn't compare dates, it compares strings. Some date formats are comparable as strings, e.g. ISO 8601 based formats: "2010-12-31" < "2011-01-01", but other date formats has to be parsed into dates to be compared, e.g. "31/12/2010" > "01/01/2011".
Parse the dates after checking that they are not empty:
...
if (startDate != '' && EndDate != '') {
var stdate = Date.parse(startDate);
var enddate = Date.parse(EndDate);
...
I am trying to make a date picker with a bunch of events that I pull from an rss feed. To make the datepicker I pretty much copy this post: jQuery UI Datepicker : how to add clickable events on particular dates?
The issue I am having is that I keep getting the error event.Date is undefined. I think this may be because of how I am passing in the dates. The dates come from a collection of strings on page load, that are converted like this:
//Convert objects
currentEventInformationString = JsonConvert.SerializeObject(currentStoreEventInformation);
eventDatesString = JsonConvert.SerializeObject(storeEventDates);
Where currentEventInformationString is a collection of strings containing a title, description, and link and eventDateString is a collection of strings that are dates (I get it from a method that returns date.ToShortDateString();
I then add all of my dates to an event array like so (in js):
//Adds each event to the date picker
for (var x = 0; x < eventDates.length; x++) {
//Adds event
events[x] = [{ Title: currentEvents[x].title.toString(), Date: new Date(eventDates[x].toString()) }];
}
I have then tried running a console.debug(events[x].Title + " " + events[x].Date); but every time I undefined undefined
When I run a debug like this:
console.debug(currentEvents[x].title.toString() + " " + eventDates[x].toString());
I get the correct values so I know that that is not the issue.
Any suggestions?
Also: I know that the question seems vague so I tried to include as much sample code as I thought was relevant. If you need more let me know. To see how the date picker is made look at the link.
Edit Here is how I declare events:
//Current event
var events = new Array(eventDates.length);
I think you have a stray set of brackets. This:
events[x] = [{
Title: currentEvents[x].title.toString(),
Date: new Date(eventDates[x].toString())
}];
Is assigning an array that contains one object literal to events[x] but I think you just want to assign an object to events[x]:
events[x] = {
Title: currentEvents[x].title.toString(),
Date: new Date(eventDates[x].toString())
};
We develop an established software which works fine on all known computers except one. The problem is to parse strings that begin with "8". It seems like "8" in the beginning of a string is a reserved character.
Parsing:
int.Parse("8") -> Exception message: Input string was not in a correct format.
int.Parse("80") -> 0
int.Parse("88") -> 8
int.Parse("8100") -> 100
CurrentCulture: sv-SE
CurrentUICulture: en-US
The problem is solved using int.Parse("8", CultureInfo.InvariantCulture). However, it would be nice to know the source of the problem.
Question: Why do we get this behaviour of "8" if we don't specify invariant culture?
Additional information:
I did send a small program to my client achieve the result above:
private int ParseInt(string s)
{
int parsedInt = -1000;
try
{
parsedInt = int.Parse(s);
textBoxMessage.Text = "Success: " + parsedInt;
}
catch (Exception ex)
{
textBoxMessage.Text =
string.Format("Error parsing string: '{0}'", s) + Environment.NewLine +
"Exception message: " + ex.Message;
}
textBoxMessage.Text += Environment.NewLine + Environment.NewLine +
"CurrentCulture: " + Thread.CurrentThread.CurrentCulture.Name + "\r\n" +
"CurrentUICulture: " + Thread.CurrentThread.CurrentUICulture.Name + "\r\n";
return parsedInt;
}
Update
I stumbled across this link, a bug in the microsoft connect database:
https://connect.microsoft.com/VisualStudio/feedback/details/253265/int32-parse-fails-to-convert-the-string-0-zero-on-some-systems
It seems like there's an issue with similiar symptoms, but no real root cause. If anyone could elaborate on this I would be grateful!
For the sv-SE culture 8 represents CurrencyNegativePattern and that's why you're getting the error you describe.
You can check this by running the following example:
var ci = new CultureInfo("sv-SE");
var nfi = (NumberFormatInfo)ci.GetFormat(typeof(NumberFormatInfo));
Console.WriteLine(nfi.CurrencyNegativePattern);
Console.WriteLine(nfi.CurrencyPositivePattern);
This will output:
// 8
// 3
You can explicitly say that you are parsing an integer and not a currency by using the Parse overload that accepts a NumberStyles enumeration.
Int32.Parse("8", NumberStyles.Integer, new CultureInfo("sv-SE"));
This time since you are specifying that you're parsing an integer no error will occur.
However, IIRC the Int32.Parse should interpret the input as an integer by default, so why you're getting to the error with that sample code is beyond me.
Update:
From the information you recently added it seems that you should make sure that the problem is not external. This is, if the user for example changed the positive sign setting of the windows locale to 8 it would be normal and make perfect sense for you to get the error you are obtaining. It would be just like setting the + as the positive sign and then trying to parse it:
var ci = new CultureInfo("sv-SE");
var nfi = (NumberFormatInfo)ci.GetFormat(typeof(NumberFormatInfo));
nfi.PositiveSign = "+";
Int32.Parse("+", nfi); // This will throw
Ask the user for it's locale registry settings like indicated in the Connect issue and check that they are what you would expect.
Side note: Welcome to SO and by the way next time you need to add further information to your question you should edit it instead of providing it in an answer.