I am trying to get input from a user, lookup the input value in an Excel column and return the value of the cell on the right side of the matching value.
This is what I came up with. As long as I replace %index% with a number, it will return a value from the Excel file.
The error I receive tells me there is a 'type mismatch' where I use %index% in
value := workbook.Sheets("Sheet1").Cells(%index%, 1).Value
Any ideas how to fix the type mismatch?
#a::
workbook := ComObjGet("somepath\tester.xlsx")
InputBox, OutputVar, Question 1, What are you looking for?
if (OutputVar)
MsgBox, Let me do this for you.
intent = OutputVar
index = 1
value = ""
Loop {
index := %index% + 1
value := workbook.Sheets("Sheet1").Cells(%index%, 1).Value
}
Until %intent% = %value%
SendInput, workbook.Sheets("Sheet1").Cells(%index%, 2).Value
Return
Use index, not %index%, in expressions. Also, you can use the built-in A_INDEX variable inside of loops
Here's your corrected code:
#a::
workbook := ComObjGet("somepath\tester.xlsx")
MAX_ROWS := 10
InputBox intent, Question 1, What are you looking for?
if ( ErrorLevel == 0 && intent ) {
Loop %MAX_ROWS% {
if ( intent == workbook.Sheets("Sheet1").Cells(A_Index, 1).Value ) {
SendInput % workbook.Sheets("Sheet1").Cells(A_Index, 2).Value
return
}
}
MsgBox 48, Not Found, "%intent%" not found in column a
}
return
Notes:
You cannot use substitution when a command takes an expression
ErrorLevel == 0 means OK was pressed. See InputBox
SendInput % makes the line use expression mode; everything following "% " is evaluated as an expression
Your loop never exits if intent is not found in the spreadsheet
Related
I'm creating an app in App Designer. What I would like to do is when selecting one or multiple options, these get assigned a value of 1.
The list(i.e. "Column") is read in the following way and list options are assigned to a struct variable with a default value of 0.
table1 = readtable("file.xls");
for i = 1:length(rmmissing(table1{:,"Column"}))
s.(char(rmmissing(table1{i,"Column"}))) = 0;
end
This outputs the following table.
s.Anna = 0
s.Bett = 0
s.Cyrielle = 0
s.Dylan = 0
My problem is that I can't figure out a way of updating the value from 0 to 1, whenever I highlight one of the options. I don't know how to essentially pick up a selected value and updating it.
So as an example, If I highlight "Anna" and "Cyrielle", these should update to 1, as shown below.
s.Anna = 1
s.Bett = 0
s.Cyrielle = 1
s.Dylan = 0
I tried an if statement like. Whilst this works, it means I have to hard-code the names, which I don't want. So it needs to dynamically pick out the name that is selected.
if app.ColumnListBox.Value == "Anna"
s.Anna = 1;
else
s.Anna = 0;
end
The listbox would look like this:
Listbox
The output I get when selecting one name is:
s =
struct with fields:
Anna: 1
Bett: 0
Cyrielle: 0
Dylan: 0
However if I select multiple options, everything goes to 0:
Multiple names
s =
struct with fields:
Anna: 0
Bett: 0
Cyrielle: 0
Dylan: 0
The code now is as follows:
names = fieldnames(s);
for j = 1:numel(names)
name = names{j};
if app.ListBox.Value == string(name)
s.(name) = 1;
else
s.(name) = 0;
end
end
assignin("base","s",s)
Any help would be much appreciated!
You should be able to make your if condition less hard coded with something like
names = fieldnames(s);
for iField = 1:numel(names)
% Assign current name to variable, e.g. "Anna"
name = names{iField};
% loop over the fields and check if selected
if app.ColumnListBox.Value == string(name)
s.(name) = 1;
else
s.(name) = 0;
end
i just want to know what this formula means .need help. please elaborate with if else statements.
=(IF(D11<=49.69,8.2404,IF(D11<50,((50-D11)*100*0.2084)+1.78, IF(D11>50.04, 0, ((50.05-D11)*100*0.356)))))
The syntax of the IF function in Excel is =IF(condition,value1,value2) where condition is something that evaluates to either TRUE or FALSE. value1 and value2 can be anything valid for insertion into an Excel cell: number, text or a formula. In the question, value2 is a formula which just happens to be another IF function and which also happens to contain further IF's in its arguments.
You can think of an IF in programming terms as
`If Condition Then Value1 Else Value2 End If'
The Help system in Excel is usually quite useful and a lot quicker than posting here and waiting for replies.
this is the logic:
If (D11<=49.69) Then
8.2404
Else
If (D11<50) Then
((50-D11)*100*0.2084)+1.78
Else
If (D11>50.04) Then
0
Else
((50.05-D11)*100*0.356)
End if
End If
End if
translated in php as:
if ($D11 <= 49.69) {
$x = 8.2404;
} elseif ($D11 < 50) {
$x = ((50-$D11)*100*0.2084)+1.78;
} elseif ($D11>50.04) {
$x = 0;
} else {
$x = ((50.05-$D11)*100*0.356)
}
I know there is strings.Index and strings.LastIndex, but they just find the first and last. Is there any function I can use, where I can specify the start index? Something like the last line in my example.
Example:
s := "go gopher, go"
fmt.Println(strings.Index(s, "go")) // Position 0
fmt.Println(strings.LastIndex(s, "go")) // Postion 11
fmt.Println(strings.Index(s, "go", 1)) // Position 3 - Start looking for "go" begining at index 1
It's an annoying oversight, you have to create your own function.
Something like:
func indexAt(s, sep string, n int) int {
idx := strings.Index(s[n:], sep)
if idx > -1 {
idx += n
}
return idx
}
No, but it might be simpler to apply strings.Index on a slice of the string
strings.Index(s[1:], "go")+1
strings.Index(s[n:], "go")+n
See example (for the case where the string isn't found, see OneOfOne's answer), but, as commented by Dewy Broto, one can simply test it with a 'if' statement including a simple statement:
(also called 'if' with an initialization statement)
if i := strings.Index(s[n:], sep) + n; i >= n {
...
}
Following is an example program in BASIC. Can someone tell me what this function returns if the marked condition is not true? I have to port the program to C++ and need to understand it. I have no BASIC knowledge - please bear with simple question.
FUNCTION CheckPoss (u)
tot = tot + 1
f = 0
SELECT CASE u
CASE 2
f = f + CheckIntersection(1, 3, 2, 1) 'A
CASE 3
f = f + CheckIntersection(2, 3, 3, 1) 'B
END SELECT
IF f = 0 THEN <============== This condition if true,
CheckPoss = 1 <============== then return value is 1
IF u = 9 THEN
PrintSolution
END IF
END IF
END FUNCTION
This is a good example of bad programming. First some unknown global variable is changed in this function. "tot = tot + 1"! Second line "F" is another unknown global variable is assigned "0". Or is this the only place this variable is used? In that case it is a variant implicitly declared here. Use a dim to declare it. It is legal in basic to do this. Globals should be passed as arguments to the function like this:
function CheckPoss(u as integer, tot as integer) as integer
dim f as integer
f=0
It is all about good practice so the input is clear and output is clear and all variable assignments should be through arguments passed to the function.
The return type is not declared either. Is this visual basic? or is it some older basic? Anyway the return type is a variant in case of visual basic. Older basic would be an integer type.
The output from this function will mostly likely be a zero if the condition is not met! That should also be clear in the code and it is not clear as it is, and I understand why you ask. I am amazed this piece of code comes from a working program.
Good luck with your project!
I don't know exactly that this function do.
On VB.net, the function follow the structure:
Public function CheckPoss(Byval u as integer)
... ' Just commands
return u ' Or other variable
end function
If not exist the 'return' command, the return of function will be 'null' character.
On C, The function will be:
int CheckPoss(int u){
tot++; // Increment tot variable (need be declared)
int f = 0;
switch(u){
case 2:
f += CheckIntersection(1, 3, 2, 1); // A
break;
case 3:
f += CheckIntersection(2, 3, 3, 1); // B
break;
}
if (f == 0){
if (u == 9){
PrintSolution();
}
return 1;
}
}
The return command need be the last command of this function. At case f != 0, the function must return trash (some value or character).
My suggestion is:
int CheckPoss(int u){
tot++; // I think that this must count how times you call this function
int f;
if(u == 2){
f = CheckIntersection(1, 3, 2, 1); // A
}else if(u == 3){
f = CheckIntersection(2, 3, 3, 1); // B
}else{
f = 1; // Case else
}
if (f == 0){
if (u == 9)
PrintSolution();
return 1;
}
}
I have a script looping for 8 numbers, skipping negative and return the largest as follows:
biggest = 0
entry = 0
loop, 8
{
; MsgBox %A_Index%
if NegativeReadings%A_Index% not contains - ;filter out readings that are negative
{
; MsgBox % AttributeReadings%A_Index%
MsgBox %biggest%
; MsgBox % AttributeReadings%A_Index%
if (AttributeReadings[A_Index] > biggest)
{
biggest := AttributeReadings[A_Index]
entry = %A_Index%
}
}
}
MsgBox %entry%
When I feed in some a sample image with 100,100,150,100,50,100,110,75, the OCR returns the object array result correctly but the numeric comparison fails
I'm getting MsgBox %biggest% = 0,100,100,150,150,50,50,50 => %entry% = 8
Something wrong happens in between (50 > 150) I have little clue in dealing with data types in ahk, any help is welcomed
Ok, I figured it out on second shot tonight, the OCR is returning a string with tailing spaces, so it led to alphabetic comparison as mentioned by admin.
Trimmed it with regexp now it works just fine
Here is the code snippet for anyone who may come across this similar issue
#SingleInstance force
#Include OCR.ahk
; sleep 5000
OCR()
; global
{
AttributeReadings := Object()
loop, 8
{
NegativeReadings%A_Index% := GetOCR(730, (136 + (17 * (A_Index - 1))), 35, 17)
AttributeReadings[A_Index] := GetOCR(730, (136 + (17 * (A_Index - 1))), 35, 17, "numeric")
; MsgBox % AttributeReadings%A_Index%
}
biggest = 0
entry = 0
i = 0
loop, 8
{
; MsgBox %A_Index%
if NegativeReadings%A_Index% not contains - ;filter out readings that are negative
{
; MsgBox % AttributeReadings%A_Index%
; length := StrLen(biggest)
; MsgBox %biggest%, %length%
number := RegExReplace(AttributeReadings[A_Index], "([space])?", "")
MsgBox %number%
; MsgBox % AttributeReadings%A_Index%
if (number > biggest)
{
biggest := number
entry := i
}
}
i++
}
MsgBox %entry%
}
End::
OCR()
return
The code above basically reads in a list of numbers from an image and return the first largest non-negative. As to the negative filtering part, it's done in OCR since it's ok with my test cases, you may want to modify it depending what images you're working with