Using If/And for multiple criteria - excel

I am trying to use 3 different criteria with a if statement. I was actually able to get this to work and its been a few weeks since i ran the code. Now suddenly, I seem to be getting an error. I am not a 100% sure why. I was trying a few different things and i am worried i messed up something that was working before. Need some advise on whether the formatting of the IF/AND statement is correct.
Dim weekct As Variant
Dim fac1 As Variant
Dim lastrow As Integer
Dim criteria1 As Variant
criteria1 = "eng"
fac1="US"
weekct = InputBox("Enter week and year in mm yyyy format:")
For i = 2 To lastrow
'lastrow is defined earlier in the code and seems to be working
If Cells(i, "DD") = weekct And Cells(i, "DF") = fac1 And Cells(i, "X") = criteria1 Then
' DF contains the name of location and fac1 is one of the locations. col X contains the product type and criteria1 is one of the product types
APEA_wuj = APEA_wuj + 1
End If
Next i

#newbiePM, will you be able to post a picture of your error? Or at least describe how do you know it is an error, was there a debug screen? when press on the debug button did it highlight the if statement?
If you want to debug your IF statement, you can try to use the immediate window to print your variable during debug mode. Put your cursor on your IF statement and press F9 to put a breakpoint on that line, now press F5 or run the routine it will stop at the breakpoint. In the immediate window, put a ? in front of your variable and print the result. ?Cells(i, "DD") = weekct, if it shows an error it meant that the variable needed your attention.
Press CTRL + G or go to view and press the immediate window button

Related

Add a specific tag (this type --> <metaphor> sentence </metaphor>) to a specific portion of text in a box?

The job is about annotating a corpus for textual metaphor recognition. I am working on Excel in order to export a CSV file for BERT analysis. I have two columns. The first column contains streches of texts. The second column is for my annotation: if there is a metaphor I put "metaphor", if not I put "none". However, my colleague asked me to addionally add a textual mark up to the portion of text which corresponds to a metaphor. So I am manually putting the sentence in this way: <metaphor> sentence </metaphor>
. I now am wondering if there is a macro or a shortcut keyboard where I just highlight the sentece I want and I press Ctrl+ something and the sentence appears within the tag specified. Thank you very much for your help.
So the following image describes how my dataset is going to be annotated This describes how my dataset is going to be annotated and this is what is my aim:the annotation scheme. Be Aware that I added the coloure in the example only for clarification. I do not want to add colour to the tagging.
UPDATE
I have a two column dataset, as in the image 1. Column 1 contains sentences from an archive which have the word "immigrant". Column 2 indicates if there is a metaphor or not.
The annotator detect and interpret manually the presence of a metaphor. He will fill the column number 2.
When you find a sentence like this:
Does the Minister recognise the challenging fact that the flow of
economic migrants will continue until the standard of living of the
country?
I then interpret "the flow of economic migrants" as a meataphor.
So, I will put "the flow of economic migrants as metaphor" between <metaphor>... </metaphor> and I will have the following annotated sentence:
Does the Minister recognise the challenging fact that <metaphor>"the
flow of economic migrants" </metaphor> will continue until the
standard of living of the country ?
I tried to record a macro as indicated in the comments above but then it cannot be run and I do not know why.
I hope I have been clear.
UPDATE 2
MOre images from the dataset
The dataset
You did not answer my clarification question. It is good to come here from time to time, after placing a question and answer the clarification questions, if any...
Supposing that my assumption that you change the font of the text portion meaning a metaphor in Italics, please try using the next Sub (Copy it in a standard module):
Sub addMetaphorTag(c As Range)
Dim strMeth As String, i As Long, frst As Long, last As Long, boolFrst As Boolean
With c
For i = 1 To Len(.Value)
If .Characters(i, 1).Font.Italic Then
If Not boolFrst Then
boolFrst = True
frst = i
End If
ElseIf boolFrst Then
last = i - 1: Exit For
End If
Next i
strMeth = Mid(.Value, frst, last - frst + 1)
.Value = left(.Value, frst - 1) & "<metaphor>" & strMeth & "</metaphor>" & Right(.Value, Len(c.Value) - last)
'if you don't need it staying Italic, comment the next line (in CSV it does not matter, anyhow)
.Characters(frst + 10, Len(strMeth)).Font.Italic = True
End With
End Sub
It can be tested in the following way: Select a cell having a metaphor part marked in Italics and run the next code:
Sub TestAddMetaphorTag()
Dim cel As Range: Set cel = ActiveCell
addMetaphorTag cel
End Sub
If it returns as you need, the next piece of code will process all your active sheet, having the marked text in "A:A" column, for cells marked as "metaphor" in column "B:B":
Sub AddMetaphTag()
Dim sh As Worksheet, lastR As Long, i As Long
Set sh = ActiveSheet 'use here the necessary sheet
lastR = sh.Range("A" & sh.rows.count).End(xlUp).row 'last row in A:A
Application.ScreenUpdating = False: Application.Calculation = xlCalculationManual
For i = 2 To lastR
If LCase(sh.Range("B" & i).Value) = "metaphor" Then
AddMetaphorTag sh.Range("A" & i)
End If
Next i
Application.ScreenUpdating = False: Application.Calculation = xlCalculationManual
End Sub
If the range to be processed is huge, the code can be adapted to be faster, if you do not need the initially Italics part to remain in Italics...
If you want to add a shortcut to run the macro, please proceed in the next way:
a. Go in Developer Tab and press Macros from first Code section.
b. In the Macro Name list, find and select AddMetaphTag and press Options... from bottom right window.
c. Fill the key you want in the small text box, add a description (if you want) and and press OK. But take care to not overwrite some important already used such shortcuts (a, s, f, h, p etc.).
If you do not see Developer Tab on your Ribbon, go File -> Options -> Customize Ribbon (from the left side) and in the opening window, to the right you will see Main Tabs, where you should check Developer and press OK...

VBA nonsense pointing at the wrong sheet?

Some strange things are happening to me in VBA. Somedays I am coding and everything works fine, then I go out of the code and the next day when I want to run the exact same code from the day before the code doesn't go into the loop, but jumps directly into end sub().
I tried to use the Activate sheet function, it seemed to work for 10 seconds and then afterwards suddenly it didn't work again which means my code didn't go into the loop again. The reason why I was using Activate sheet function was because I was afraid that my code was pointing at the wrong excel file / sheet. I have a lot of excel files and all of the sheets in those excel files are called Sheet1 could that create problems??
To give you a concrecte example, say I day one use the following code to loop through a column:
Sub stuff()
' Sheet1.Activate
lngLastRow = Worksheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
Set sheet1ArkRng = Worksheets("Sheet1").Range("A1:Z" & lngLastRow)
Set offsheetarkrng = Worksheets("Sheet1").Range("L5")
Dim i As Integer
For i = 3 To sheet1ArkRng.Rows.Count
sheet1VirkNavn = sheet1ArkRng.Cells(RowIndex:=i, ColumnIndex:="C").Value
Next i
End Sub
Then day 1 everything works fine and the variable sheet1VirkNavn shows me the value of the rows in column C. It can be seen when I debug.
Then day 2 once I debug the exact same code from the exact same file it goes to
"For i = 3 To sheet1ArkRng.Rows.Count"
and then jumps directly into
End sub
Problem solved:
I've learned what
lngLastRow = Worksheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
means. Now it all makes sense. If you're using the above code to loop through last row you should use the same letter for the column you want to loop through...
So the case was my code wasn't getting into the loop simply because my "A" column was empty.

VBA - Excel - Finding the cell location of a userform TextBox populated by a for i loop?

What do I need to know?
How do I get the location of the data that a textbox is displaying? How do I know where it is?
What am I doing?
I have some code that loops through i and assigns it a value then pulls the cell value from a sheet based on i....so (i, 2) is simply: Row i from Column 2. This is then displayed in a userform Textbox.
What I want to do?
Add a dbl_click event, so that someone can double click on the textbox and be sent to the sheet/row/column that is being displayed. I have no issue creating the dbl_click event, but my problem appears to be how to get the cell location being displayed?
If it is relevant, this is my code for the loop:
Dim code as String
code = search.Value
For i = 2 To LastRow
If Sheet1.Cells(i, 9).Value = code Then
ssn1.Text = Sheet1.name
hb11.Text = Sheet1.Cells(i, 9).Value
End If
Next i
This is a snippet, as this goes on for awhile, hb11 runs though to hb37 - didn't see any reason to paste it all here.
The problem is, that the loop continues through, across multiple sheets as well, finding all examples of "code" so i keeps changing, after it has written the data to the TextBox - so I can't rely on (i, 9) from the loop.
I have gotten this far in terms of code:
Sub bt11_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
If hb11.Value <> ("") Then
Application.Goto Reference:=Sheet1.Range(hb11)
End If
End Sub
However this appears to be relying on the value of hb11, rather than the cell location.
I know this is a dumb question, I know, but I just can't seem to find the answer?
I get the feeling that it lies in:
Dim cell as Range
Then:
Set cell = hb11.something
But I have been through the list, cell/range gives a mismatch, and don't actually exist in the list. There is no 'linked cell' as I thought that might do it...
I am a bit lost.
Profit from using the .Tag property
I'm assuming each of your 27 textboxes refers to exactly one source range address which consists of sheetname, row and column (or column character).
If so you can profit from assigning a combined reference string (e.g. "Sheet22" & "," & i & "," & 9) to a textbox'es ►.Tag property during the initializing loop, e.g. in a comma separated way like perhaps
hb11.Tag = "Sheet22,17,9" ' << i.e. sheet name, row 17, column 9
I think it'll be easy to get all data from there:
Dim src: src = split(hb11,",")
Application.Goto Reference:= _
ThisWorkbook.Worksheets(src(0)).Range(Cells(Val(src(1)), Val(src(2))).Address), Scroll:=True
Too many hours later, I have worked this out.
Thanks to T.M. for the idea about re-writing the data out of a stored place.
Outside of any sub, I created a String - right at the top.
Dim ac1 As String
Inside my loop, I simply gave ac1 the value of i,
For i = 2 To LastRow
If Sheet1.Cells(i, 9).Value = code Then
ssn1.Text = Sheet1.name
hb11.Text = Sheet1.Cells(i, 9).Value
ac1 = i
End If
Next i
This works, because you only run through this loop, IF code exists, since the list is unique, code only exists once. So you only go into the loop once, and when you do, i = the row.
Then using T.M.'s idea, I wrote out:
Application.Goto Reference:=Sheet1.Range("A" & ac1)
This is a range reference that Goto can handle.
The advantage of this method is, because I am searching multiple sheets with multiple Textboxes, I only need ac1 for a whole sheets worth of Textboxes.
Hope this helps someone in the future.

Excel Range.Find not working the way I thought it would

So I have been trying to figure out why this isn't working and I am getting really frustrated.
When I click on my "Search" button, it takes the text from a text box, and uses that as the search criteria. I want it to skip whatever row is currently active, so that as long as I keep pressing my "Search" buttton it will move on, and not keep finding the same row. And I had it working for a long time, then I upgraded to Windows 10 and stuff stopped working. This is just the one thing I can't seem to figure out. I made some changes to my original, so this is not the same code that used to work. No matter what I do it keeps showing me the same row even though the one RIGHT BELOW it has identical data. Like in the picture below, if I search for TRACE the third row of data is selected, but when I hit "Search" again, it doesnt move to the next row like it should. I am using Range.Find(What:= , After:=) and setting the After range to the very left cell of the current activated range. Which should start the search on the next row. But that is not happening.
Private Sub Search_Next_Click()
Dim Fnd As Range
Dim S_Range as Range
Dim CurrRow As Integer: CurrRow = ActiveCell.Row
Dim CurrColumn As Integer: CurrColumn = ActiveCell.Column
'Last row of data
LastRow = Range("B24").End(xlDown).Row
AC = ActiveCell.Address
''If the Find button is pressed and the current active cell is outside the range of my data
''this makes sure that the active cell moves to the upper left of that range
If AC = "" Or CurrRow < 24 Or CurrColumn > 10 Then
AC = "B24"
Range(AC).Activate
End If
ACr = ActiveCell.Row
On Error Resume Next
Set S_range = Range("B24" & ":J" & LastRow)
Set Fnd = S_range.Find(what:=SearchBox.Text, after:=Range(AC))
FR = Fnd.Row
If FR = "" Then
MsgBox ("No Match Found")
DoCmd.CancelEvent
SearchBox.SetFocus
Exit Sub
End If
On Error GoTo 0
Scell = "B" & FR & ":J" & FR
ActiveSheet.Range(Scell).Select
ActiveSheet.Range(Scell).Activate
End Sub
OK as soon as I posted this, I figured out what I did wrong. Although I dont know why it worked in the past, and then stopped. Maybe I changed something without realizing it and screwed myself up. Anyway, I was searching for a value in the D column. Once it was found the cell with the search criteria, the cells in column B through F were selected and activated in that row. But when I hit Search again, it started after the B column of that row. I thought it would skip to the next row, but it was moving to the next column to start the search. So it ran into the same value again, and the cycle repeated.
I just changed the After criteria to
After:=Range("B" & ACr + 1)
Then it started the search on the next row like I wanted.
Im leaving this up in case anyone else comes across this mistake. Hopefully I can help someone else realize that they are not the only ones that make stupid mistakes.....

#VALUE error when copying sheets

I´m using a UDF that is basically a vlookup simplified. Here´s the code:
Function SUELDOBASICO(Columna As Integer) As Double
SUELDOBASICO = Application.WorksheetFunction.VLookup(Application.Caller.Parent.Cells(Application.Caller.Row, 3), Application.Caller.Parent.Parent.Sheets("Escalas Salariales").Range("A3:DJ23"), Columna, False)
End Function
I´ve noticed that sometimes when copying sheets(within the same workbook), I get a #VALUE error. If I "edit" the cell in Excel, changing nothing, just using F2 and Enter, the error disappears. It used to happen when simply changing windows (to Firefox, and back to Excel, for instance). That´s why I used Caller and Parent so much in the code. It is almost completely fixed, except when copying sheets sometimes. I can´t seem to find the source of the error.
Help please.
I know this isn't your exact question, but, if at all possible, I would suggest to just avoid VBA completely if that's at all an option and write your formula as follows:
=VLOOKUP(INDIRECT("C"&ROW()),'Escalas Salariales'!$A$3:$DJ$23,XXXXX,false)
and XXXXX can be the same as your Columna variable currently.
That would guarantee your code to work as needed.
Given what was discussed in the comments and trying my absolute best to ensure this works, I actually don't see anything wrong with your code and am just GUESSING it may have something to do with Application.Caller.
When this kind of thing happens to me, I try my best to just use the debugger to figure out why - That usually involves either Stop statements to be able to step into code and see what happened or Debug.Print Err.Description kind of messages.
Either way, I tried to break each part down, so, at the very least you can see where the issue comes from.
To do so, I re-worked your function (with some major overkill)....
Function SUELDOBASICO(Columna As Integer) As Double
On Error GoTo ErrorCheck
Dim CellRef As Range
Dim LookupRef As Range
Set CellRef = Cells(Application.Caller.Range("A1").Row, 3)
Set LookupRef = Application.Caller.Worksheet.Parent.Sheets("Escalas Salariales").Range("A3:DJ23")
SUELDOBASICO = Application.VLookup(CellRef, LookupRef, Columna, False)
Exit Function
ErrorCheck:
Stop
Resume
End Function
(Also note that I changed Application.WorksheetFunction.VLookup to Application.VLookup - Look at this link for an explanation)
Once you figure it out, I would, though, remove the error code from the function as that isn't a good idea for production code - Just for Debugging.
Hopefully that can give you the answers you are looking for.
Hope that helps....
UPDATE #2:
Taking into account the possibility that copying the sheet is causing this error, here's a test to see if the process gets fixed:
Function SUELDOBASICO(Columna As Integer) As Double
On Error GoTo ErrorCheck
Dim NumTimesErrored As Integer
Dim StartTime As Double
Dim WaitSeconds As Integer
NumTimesErrored = 0
Dim CellRef As Range
Dim LookupRef As Range
Set CellRef = Cells(Application.Caller.Range("A1").Row, 3)
Set LookupRef = Application.Caller.Worksheet.Parent.Sheets("Escalas Salariales").Range("A3:DJ23")
SUELDOBASICO = Application.VLookup(CellRef, LookupRef, Columna, False)
Exit Function
ErrorCheck:
' This will make it tries this "hack" up to 3 times:
If NumTimesErrored < 3 Then
StartTime = Now
WaitSeconds = 1 ' Wait one second
Loop While Now - TimeStart < TimeSerial(0, 0, WaitSeconds)
DoEvents ' Allows all the other processes to complete
Loop
' Increment the number of times you've tried this:
NumTimesErrored = NumTimesErrored + 1
' Go back to the calculation step that errored
Resume
End If
Stop
Resume
End Function
The is no need to use caller and parent.
Function SUELDOBASICO(Cell as Range, LookupRange as range, Columna As Integer) As Double
' When you call the function :
' set Cell to be the cell in column C in the same row
' Set LookupRange to Sheets("Escalas Salariales").Range("$A$3:$DJ$23")
SUELDOBASICO = Application.WorksheetFunction.VLookup(Cell, LookupRange, Columna, False)
End Function
example of formula in a cell...
=SUELDOBASICO(C10,'Escalas Salariales'!$A$3:$DJ$23)

Resources