Is there a way to prevent square brackets being inserted into my string? - apex

I seem to be getting some square brackets being inserted into my string that I am using for a dynamic SOQL query. I'm trying to check if the status of an order is one of the options chosen by the user. Usually I would be able to just throw a list after the IN clause, but because this is a string I'm not able to do so. Instead, I have a loop that iterates through the list of selected statuses and adds to the query string as needed.
I've used the exact same syntax in another org with no issues, so I'm curious as to why this would happen in another one. I've posted the version that is having the issue. Hopefully this isn't too tough to remove.
if(orderStatuses.size() > 0){
query += ' AND ccrz__OrderStatus__c IN (\''+orderStatuses[0]+'\'';
for(Integer i = 1; i < orderStatuses.size(); i++){
query += ', \''+orderStatuses[i]+'\'';
}
query += ')';
}
What I want to have is a string that looks something like
'AND ccrz__OrderStatus__c IN ('Completed', 'Order Submitted')'
But instead I get
'AND ccrz__OrderStatus__c IN ('[Completed', ' Order Submitted]')'
I've also tried using the 'replaceAll()' method to forcibly remove them before the query is run, but they still appear anyways.
query.replaceAll('[\\[\\]]','');
When only selecting one option, it formats perfectly fine without any brackets, but once more than one is picked, this happens.
Any and all help would be greatly appreciated on this one. As I mentioned above, this same exact code (granted with different objects, etc.) was giving me the correct results when run in a different org, so I'm stumped. Thanks in advance!

I was able to reproduce your issue by adding the '[' and ']' to your array "orderStatuses". If I was you, I'd look at those square brackets for your error. It is likely that the square brackets you see are literally part of the strings you're passing. There is also an extra space in the orderStatuses[1] that is further telling me you have something being added to the array you don't want earlier in the code/SQL.
var orderStatuses = [];
orderStatuses.push("[Completed");
orderStatuses.push(" Order Submitted]");
var query = ' AND ccrz__OrderStatus__c IN (\'' + orderStatuses[0] + '\'';
for (var i = 1; i < orderStatuses.length; i++) {
query += ', \'' + orderStatuses[i] + '\'';
}
query += ')';
alert(query)

Related

Converting numbers into timestamps (inserting colons at specific places)

I'm using AutoHotkey for this as the code is the most understandable to me. So I have a document with numbers and text, for example like this
120344 text text text
234000 text text
and the desired output is
12:03:44 text text text
23:40:00 text text
I'm sure StrReplace can be used to insert the colons in, but I'm not sure how to specify the position of the colons or ask AHK to 'find' specific strings of 6 digit numbers. Before, I would have highlighted the text I want to apply StrReplace to and then press a hotkey, but I was wondering if there is a more efficient way to do this that doesn't need my interaction. Even just pointing to the relevant functions I would need to look into to do this would be helpful! Thanks so much, I'm still very new to programming.
hfontanez's answer was very helpful in figuring out that for this problem, I had to use a loop and substring function. I'm sure there are much less messy ways to write this code, but this is the final version of what worked for my purposes:
Loop, read, C:\[location of input file]
{
{ If A_LoopReadLine = ;
Continue ; this part is to ignore the blank lines in the file
}
{
one := A_LoopReadLine
x := SubStr(one, 1, 2)
y := SubStr(one, 3, 2)
z := SubStr(one, 5)
two := x . ":" . y . ":" . z
FileAppend, %two%`r`n, C:\[location of output file]
}
}
return
Assuming that the "timestamp" component is always 6 characters long and always at the beginning of the string, this solution should work just fine.
String test = "012345 test test test";
test = test.substring(0, 2) + ":" + test.substring(2, 4) + ":" + test.substring(4, test.length());
This outputs 01:23:45 test test test
Why? Because you are temporarily creating a String object that it's two characters long and then you insert the colon before taking the next pair. Lastly, you append the rest of the String and assign it to whichever String variable you want. Remember, the substring method doesn't modify the String object you are calling the method on. This method returns a "new" String object. Therefore, the variable test is unmodified until the assignment operation kicks in at the end.
Alternatively, you can use a StringBuilder and append each component like this:
StringBuilder sbuff = new StringBuilder();
sbuff.append(test.substring(0,2));
sbuff.append(":");
sbuff.append(test.substring(2,4));
sbuff.append(":");
sbuff.append(test.substring(4,test.length()));
test = sbuff.toString();
You could also use a "fancy" loop to do this, but I think for something this simple, looping is just overkill. Oh, I almost forgot, this should work with both of your test strings because after the last colon insert, the code takes the substring from index position 4 all the way to the end of the string indiscriminately.

Filter form based on unbound control value

I have a form bound to a query, except for one field that I am leaving unbound. The idea is that the user will enter a value in that textbox and press a button to bring up the record. I have some code that I thought would work based on the interwebs. When I use DoCmd.ApplyFilter(filter_string) I get a popup asking for the value to filter on (which is not what I want). When I go ahead and paste it in, the form does not get filled. When I use Me.Form.Filter = filter_string, sometimes the form fills, but always with the same record, regardless of what the filter_string says. An example filter_string is
filter_string = "InventoryDetailsID = 'B01MFC000100/01'"
I have another similar form that, instead of filling with an existing query, generates the query (with 5 joins) and fills the form from the resulting recordset. It works just fine, but is slow because it has to run the query each time. That is why I want to use a method where I generate the query once, and then filter it.
Edit
Oh, and I also tried using a variant on the run-the-query-every-time approach, where I query the already generated query (the one I'm trying to filter). I'm using:
query_string = "SELECT * FROM qry_ISBN_All WHERE InventoryDetailsID LIKE '" & Me.InventoryDetailsID & "';"
But I get the error Run-time error '3061' Too few parameters, expected 1
Edit II
Private Sub btn_Seek_Click()
Dim temp As String
filter_string = "InventoryDetailsID = '" & Me.InventoryDetailsID & "'"
Me.temp = filter_string
Me.FilterOn = True
Me.Form.Filter = filter_string
Me.FilterOn = True
'DoCmd.ApplyFilter (filter_string)
' Dim query_string As String
' query_string = "SELECT * FROM qry_ISBN_All WHERE InventoryDetailsID LIKE '" & Me.InventoryDetailsID & "';"
End Sub
Typical filter string is given. It is printed to the form control Me.temp.
After this line:
Me.Filter = filter_string
Add this in:
Me.FilterOn = True
Also I agree, run the query every time approach is definitely overkill. The filter should provide you with the functionality you seek. You just simply have to "turn it on" after you set it.

Formula won't display when certain fields are null

Similar to my first question. I want to show my address in a text box containing the fields as follows
{Company}
{AddLine1}
{AddLine2}
{ZIP}{State}{City}
{Country}
The line that concerns me (and hopefully some of you guys) is {ZIP} {City} {State}. What I want to produce is a consistent addressing format, so that there will be no blank space or indentation even if a ZIP, City or State field has been left blank in the DB. This line should still line up with the rest of the rows and not be indented. I also wish to insert commas between zip, state, city where they are relevant and leave them out where not. For this I have written a formula. Below:
If isnull({BILL_TO.ZIP}) or trim({BILL_TO.ZIP})= "" Then "" else {BILL_TO.ZIP}
+
(If isnull({BILL_TO.State}) or trim({BILL_TO.State})= "" Then ""
else(If not isnull({BILL_TO.ZIP}) and length(trim({BILL_TO.ZIP})) <> 0 Then ", " else "") + {BILL_TO.State})
+
(If isnull({BILL_TO.CITY}) or length(trim({BILL_TO.CITY})) = 0 Then ""
else(
If (not isnull({BILL_TO.State}) and length(trim({BILL_TO.State})) <> 0)
or
(not isnull({BILL_TO.Zip}) and length(trim({BILL_TO.Zip})) <> 0)
Then ", " else "")+ {BILL_TO.CITY}))
The problem is that when there is only a city (no state or zip entered) the formula itself will not display. It does however display when the others are present.
Can anyone see a bug in this code??? Its killing me
Thanks for the help.
Look forward to hearing from you guys!
There are a whole lot of if-then-elses going on in that formula so it's hard to tell, but if it's not displaying anything that probably means that you're using a field somewhere without handling its null condition first. Something simpler might be your best bet:
local stringvar output;
if not(isnull({Customer.Postal Code})) then output:=trim({Customer.Postal Code}) + ', ';
if not(isnull({Customer.Region})) then output:=output + trim({Customer.Region}) + ', ';
if not(isnull({Customer.City})) then output:=output + trim({Customer.City}) + ', ';
left(output,length(output)-2)
Create a formula field for each database field. For example:
// {#CITY}
If Isnull({BILL_TO.CITY}) Then
""
Else
Trim({BILL_TO.CITY})
// {#STATE}
If Isnull({BILL_TO.STATE}) Then
Space(2)
Else
Trim({BILL_TO.STATE})
// {#ZIP}
If Isnull({BILL_TO.ZIP}) Then
Space(5) //adjust to meet your needs
Else
Trim({BILL_TO.ZIP})
Embed each formula field in a text object.
Format text object and its fields to meet your need.
** edit **
I you have data-quality issues, address them in the STATE and ZIP formulas (because they will be a constant length). I would add the commas and spacing the text object.

MongoDB Query.And does not support matches

I am running a search phrase against a MongoDB collection. My phrase may have more than one term in it e.g. search for 'pete smit'. I therefore need to use regular expressions to provide a 'starts with' function. I am therefore creating an array of Query.Matches queries, adding them to a QueryComplete array, and then using a Query.And to run them.
Code is as follows:
// searchTerm will be something like 'pete smit'
string[] terms = searchTerm.Split(' ');
MongoDB.Driver.Builders.QueryComplete[] qca;
qca = new MongoDB.Driver.Builders.QueryComplete[terms.Length];
for (int i = 0; i < terms.Length; i++)
{
regex = "/(\\b" + terms[i] + ")+/i"; // Good, but only single term (\b is start of word)
qca[i] = MongoDB.Driver.Builders.Query.Matches("companyname", regex);
}
//MongoDB.Driver.Builders.QueryComplete qry = MongoDB.Driver.Builders.Query.Or(qca); // This works
MongoDB.Driver.Builders.QueryComplete qry = MongoDB.Driver.Builders.Query.And(qca); // This fails
On executing the Query.And I get an error stating:
Query.And does not support combining equality comparisons with other operators (field: 'companyname')
It works fine if I use Query.Or, but doesn't work if I use Query.And. Can anyone suggest a workaround? Thanks very much.
Until MongoDB supports $and all the subqueries passed to Query.And must be for different fields (so you can't apply different regular expressions to the same field).
The workaround is to encapsulate the multiple search terms in a single regular expression, as follows:
string[] terms = searchTerm.Split(' ');
regex = "/";
for (int i = 0; i < terms.Length; i++)
{
regex += "(?=.*\\b" + terms[i] + ")";
}
regex += ".*/i";
MongoDB.Driver.Builders.QueryComplete query = MongoDB.Driver.Builders.Query.Matches("companyname", regex); // The ^ matches the start of the string
See Regular expression to match all search terms
MongoDB's $and operator is now implemented and fully functional. See http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24and for usage so your original MongoDB.Driver.Builders.Query.And(qca); should now work.
[this is likely too late to help the original poster, but other users who find this question from a search can benefit]

How to convert a numeric variable to a string in MATLAB

A=rand(10)
B=find(A>98)
How do you have text saying "There were 2 elements found" where the 2 is general i.e. it isn't text, so that if I changed B=find(A>90) it would automatically no longer be 2.
some_number = 2;
text_to_display = sprintf('There were %d elements found',some_number);
disp(text_to_display);
Also, if you wanted to count the number of elements greater than 98 in A, you should one of the following:
numel(find(A>98));
Or
sum(A>98);
sprintf is a very elegant way to display such data and it's quite easy for a person with a C/C++ background to start using it. If you're not comfortable with the format-specifier syntax (check out the link) then you can use:
text_to_display = ['There were ' num2str(some_number) ' elements found'];
But I would recommend sprintf :)