How are the double-quotes managed when I put this code into a loop? - excel

On SO, I was just given two answers that both work when called a single time. Now I want to put them in a loop and loop over several rows of data. However, I'm having a heck of time getting the code correct. I'm suspect it has to how I'm handling the double quotes.
The stand alone code lines are as follows.
Var = ActiveSheet.Evaluate("And(A1:F1)") and
Var = Application.WorksheetFunction.And(Range("A1:F1"))
for the first example I tried:
for i = 2 to 20
Var = ActiveSheet.Evaluate("And(A & i & :F & i)")
Next i
This produces "Error 2015"
for the second:
for i = 2 to 20
Var = Application.WorksheetFunction.And(Range("A" & i & ":F" & i))
Next i
This produces a line of red code
What am I doing wrong?

The Visual Basic Editor is making this harder than it should be, because its default syntax highlighting is making string literals the same color as identifiers:
You can change that under Tools/Options, and make Identifier Text a different color - here teal:
Now string literals are still black, but now identifiers look visually distinctive:
What you want to make sure, is that your variables are syntax-highlighted like identifiers - so they're teal, not black - like in your second example:
Contrast with your first attempt, where i doesn't get syntax-highlighted as the identifier it should be:
And since you know that i is a VBA variable and you want VBA to concatenate its value into this string, then i being syntax-highlighted as any other string literal (and not as an identifier) is your visual cue that something's off!
Compare to #JNevill's fixed version:
With Identifier Text having a different syntax highlighting than string literals in the editor, it becomes much easier to quickly locate a variable that's accidentally inside a string literal.
That first snippet isn't working, because ActiveSheet.Evaluate takes its parameter and gives it to Excel's expression evaluation engine, ...which has no idea what to do with this i. Variable i only exists in the execution context of the VBA code: only VBA code can evaluate its value.

Related

how do I get rid of leading/trailing spaces in SAS search terms?

I have had to look up hundreds (if not thousands) of free-text answers on google, making notes in Excel along the way and inserting SAS-code around the answers as a last step.
The output looks like this:
This output contains an unnecessary number of blank spaces, which seems to confuse SAS's search to the point where the observations can't be properly located.
It works if I manually erase superflous spaces, but that will probably take hours. Is there an automated fix for this, either in SAS or in excel?
I tried using the STRIP-function, to no avail:
else if R_res_ort_txt=strip(" arild ") and R_kom_lan=strip(" skåne ") then R_kommun=strip(" Höganäs " );
If you want to generate a string like:
if R_res_ort_txt="arild" and R_kom_lan="skåne" then R_kommun="Höganäs";
from three variables, let's call them A B C, then just use code like:
string=catx(' ','if R_res_ort_txt=',quote(trim(A))
,'and R_kom_lan=',quote(trim(B))
,'then R_kommun=',quote(trim(C)),';') ;
Or if you are just writing that string to a file just use this PUT statement syntax.
put 'if R_res_ort_txt=' A :$quote. 'and R_kom_lan=' B :$quote.
'then R_kommun=' C :$quote. ';' ;
A saner solution would be to continue using the free-text answers as data and perform your matching criteria for transformations with a left join.
proc import out=answers datafile='my-free-text-answers.xlsx';
data have;
attrib R_res_ort_txt R_kom_lan length=$100;
input R_res_ort_txt ...;
datalines4;
... whatever all those transforms will be performed on...
;;;;
proc sql;
create table want as
select
have.* ,
answers.R_kommun_answer as R_kommun
from
have
left join
answers
on
have.R_res_ort_txt = answers.res_ort_answer
& have.R_kom_lan = abswers.kom_lan_answer
;
I solved this by adding quotes in excel using the flash fill function:
https://www.youtube.com/watch?v=nE65QeDoepc

Replacing "invisible" special characters with something legible

About twelve years ago, I wrote a small VB.NET application that loads strings from files. These strings may contain one or more of the following characters: à, è, é, ì, ò, ù, ä, ö. The application uses a special custom font (JazzText Extended) that does not have those special characters. Yet, I somehow managed to make the application display words correctly in that font, and twelve years later, I have no idea how - thanks for not leaving a line of comment, past me!
The program has the following routine:
Private Sub SetWord(ByVal word() As String)
Dim nword(3) As String
nword(0) = word(0)
nword(1) = word(1)
nword(2) = word(2)
For i As Integer = 0 To 2
nword(i) = nword(i).Replace("à", "")
nword(i) = nword(i).Replace("é", "")
nword(i) = nword(i).Replace("è", "")
nword(i) = nword(i).Replace("ì", "ê")
nword(i) = nword(i).Replace("ò", "")
nword(i) = nword(i).Replace("ù", "")
nword(i) = nword(i).Replace("ä", "")
nword(i) = nword(i).Replace("ö", "")
Next
lblItaWord.Text = nword(0).ToUpper
lblEngWord.Text = nword(1).ToUpper
lblFinWord.Text = nword(2).ToUpper
End Sub
What it does is, it takes an array that contains three words, and for each of those three words, it looks if it contains any of the special characters. If it does, it replaces them with... something, makes the words all caps, and then assigns each of them to one of three labels.
In Visual Studio, the replacement characters look like empty strings. I had to put the cursor in between the quotation marks to realise that it was in fact not an empty string and there was an invisible character there. Here on SO... I'm not sure what you'll see. You might see just a square, or some other weird character. (The ê character is an exception, it seems to display in the same way everywhere.)
If you copypaste any of the invisible/square characters to Google and search for it, you'll get a different representation that uses two characters—for example, the first one translates to ‡. Using this pair in place of the invisible/square character in the Replace method does not produce the correct result. FYI, the encoding I use to read the files (the default one used by IO.StreamReader if you don't specify any encoding) works fine: if I use a more standard font, all special characters display correctly without using the SetWord sub at all.
Now, I have absolutely no idea how those characters, whatever they may be, manage to make the app display correctly the words when the font I use does not have those characters. I have no idea how I found out about this trick, either. Right now, my problem is that I would like to replace those squares/invisible characters with something intelligible, and I have no idea how. Any ideas?

How to concatenate variable to Range Shortcut [ ]?

I prefer to use Range Shortcut [ ] instead of Range(" ").
But I cannot concatenate variable to it.
ActiveSheet.Range("A2:A" & LastRow).Select ‘This works
ActiveSheet.[A2:A & LastRow].Select ‘not works
I got error Object required.
You cannot add variables within the brackets. That's why it's returning the object required error.
ExcelHero did tests and found that the brackets run slower than when range is clearly defined in the code:
http://www.excelhero.com/blog/2010/06/when-working-in-vba-we.html
Use Evaluate to do what you want to do
ActiveSheet.Evaluate("A2:A" & lastRow).Select
Using square brackets (for example, "[A1:C5]") is identical to calling
the Evaluate method with a string argument.
Further reading
refer-to-cells-by-using-shortcut-notation
excel.application.evaluate
PS As the OP is after having a string variable in the expression with [] and as I do not think that this is possible another quote from the documentation to support my point of view.
The advantage of using square brackets is that the code is shorter.
The advantage of using Evaluate is that the argument is a string, so
you can either construct the string in your code or use a Visual Basic
variable.

Lua: Parsing and Manipulating Input with Loops - Looking for Guidance

I am currently attempting to parse data that is sent from an outside source serially. An example is as such:
DATA|0|4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_
This data can come in many different lengths, but the first few pieces are all the same. Each "piece" originally comes in with CRLF after, so I've replaced them with string.gsub(input,"\r\n","|") so that is why my input looks the way it does.
The part I would like to parse is:
4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_
The "4" tells me that there will be four lines total to create this file. I'm using this as a means to set the amount of passes in the loop.
The 7x5 is the font height.
The 1 is the xpos.
The 25 is the ypos.
The variable data (172-24 in this case) is the text at these parameters.
As you can see, it should continue to loop this pattern throughout the input string received. Now the "4" can actually be any variable > 0; with each number equaling a set of four variables to capture.
Here is what I have so far. Please excuse the loop variable, start variable, and print commands. I'm using Linux to run this function to try to troubleshoot.
function loop_input(input)
var = tonumber(string.match(val, "DATA|0|(%d*).*"))
loop = string.match(val, "DATA|0|")
start = string.match(val, loop.."(%d*)|.*")
for obj = 1, var do
for i = 1, 4 do
if i == 1 then
i = "font" -- want the first group to be set to font
elseif i == 2 then
i = "xpos" -- want the second group to be set to xpos
elseif i == 3 then
i = "ypos" -- want the third group to be set to ypos
else
i = "txt" -- want the fourth group to be set to text
end
obj = font..xpos..ypos..txt
--print (i)
end
objects = objects..obj -- concatenate newly created obj variables with each pass
end
end
val = "DATA|0|4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_"
print(loop_input(val))
Ideally, I want to create a loop that, depending on the var variable, will plug in the captured variables between the pipe deliminators and then I can use them freely as I wish. When trying to troubleshoot with parenthesis around my four variables (like I have above), I receive the full list of four variables four times in a row. Now I'm having difficulty actually cycling through the input string and actually grabbing them out as the loop moves down the data string. I was thinking that using the pipes as a means to delineate variables from one another would help. Am I wrong? If it doesn't matter and I can keep the [/r/n]+ instead of each "|" then I am definitely all for that.
I've searched around and found some threads that I thought would help but I'm not sure if tables or splitting the inputs would be advisable. Like these threads:
Setting a variable in a for loop (with temporary variable) Lua
How do I make a dynamic variable name in Lua?
Most efficient way to parse a file in Lua
I'm fairly new to programming and trying to teach myself. So please excuse my beginner thread. I have both the "Lua Reference Manual" and "Programming in Lua" books in paperback which is how I've tried to mock my function(s) off of. But I'm having a problem making the connection.
I thank you all for any input or guidance you can offer!
Cheers.
Try this:
val = "DATA|0|4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_"
val = val .. "|"
data = val:match("DATA|0|%d+|(.*)$")
for fh,xpos,ypos,text in data:gmatch("(.-)|(.-)|(.-)|(.-)|") do
print(fh,xpos,ypos,text)
end

C# 4.0 function to check for first four characters in the string

I need to validate for valid code name.
So, my string can have values like below:
String test = "C000. ", "C010. ", "C020. ", "C030. ", "CA00. ","C0B0. ","C00C. "
So my function needs to validate below conditions:
It should start with C
After that next 3 characters should be numeric before .
Rest it can be anything.
So in above string values, only ["C000.", "C010.", "C020.", "C030."] are valid ones.
EDIT:
Below is the code I tried:
if (nameObject.Title.StartsWith(String.Format("^[C][0-9]{3}$",nameObject.Title)))
I'd suggest a regex, for example (written off the top of my head, may need work):
string s = "C030.";
Regex reg = new Regex("C[0-9]{3,3}\\.");
bool isMatch = reg.IsMatch(s);
This regex should do the trick:
Regex.IsMatch(input, #"C[0-9]{3}\..*")
Check out http://www.techotopia.com/index.php/Working_with_Strings_in_C_Sharp
for a quick tutorial on (among other things) individual access of string elements, so you can test each element for your criteria.
If you think your criteria may change, using regular expressions gives you maximum flexibility (but is more runtime intensive than regular string-element evaluation). In your case, it may be overkill, IMHO.

Resources