I have one data worksheet which is as per below format (100+ cols)
then I have another file containing some rules (multiple rules for each column in data file). I formulated vba conditions for every rule; for example, one rule was to check column A of data file should have only BP or Trip value for all rows (50K+ rows). So I translated that to below VBA
DataWB.Worksheets(1).Cells(J,X) = "BP" OR DataWB.Worksheets(1).Cells(J,X) = "Trip"
validate button code
f = Trim(ThisWorkbook.Worksheets(1).Cells(2, 3))
f = Replace(f, "J", 2)
f = Replace(f, "X", 1)
Debug.Print Application.Evaluate(f)
now problem is that evaluate throws type mismatch and if I use CBOOL it always return TRUE. I tried different variations too (like adding = or ? prefix) but nothing seem working. Any help will be highly appreciated.
Evaluate cant understand VBA Code rather excel worksheet formula can only be used, so i replaced with formula as in picture and it works perfectly now
For J = 2 To lRow
For x = 2 To 26
f = Trim(ThisWorkbook.Worksheets(1).Cells(x, 3))
f = Replace(f, "WB", SourceWB.Name)
f = Replace(f, "WS", SourceWB.Worksheets(1).Name)
f = Replace(f, "R#", J)
test = Evaluate(f)
If Not test Then Call LogError(J, x)
Next x
Next J
Related
Is there any way to terminate an IIf() statement if it doesn't return a value?
This is what my code looks like:
Do While Sheets("testsheet").Cells(1, Z) <> ""
text1 = Sheets("testsheet").Cells(1, Z).Value
vLook = Application.HLookup(text1, lookupRange, u, False)
Sheets("Kilepok").Cells(i, Z).Value = IIf(IsError(vLook), ????, vLook)
Z = Z + 1
Loop
The code runs through the header (z), and looks for a value. If it finds a value, I would like to paste this in those cases (when there is no error in vlook). In other cases, I don't want to modify the value of the current cell.
Either
Sheets("Kilepok").Cells(i, Z).Value = IIf(IsError(vLook), Sheets("Kilepok").Cells(i, Z).Value, vLook)
or
If Not IsError(vLook) Then Sheets("Kilepok").Cells(i, Z).Value = vLook
will do the job.
But note that the first will re-write the cell's value (which makes it slow) and if there is a forumla in it, it will be converted into a value. So the second one would be the preferred solution.
I have searched this forum and found several articles related to the same error message. Yet, none is related to my problem.
I have a table in Word with the following properties:
wddoc.tables(1).Rows.Count : 15
wddoc.tables(1).Columns.Count : 4
I was trying to copy the table to Excel using the following code:
For m = 1 To 15
For l = 1 To 4
ActiveSheet.Cells(m, l) = wdDoc.Tables(1).Cell(m, l)
Next l
Next m
The code worked fine for the first three rows but when it came to the fourth row (m=4, l=1), it threw the titled error message. What gives?
To get the correct results from a Word table with merged or split cells, use code like:
Dim wdCell As Object
For Each wdCell In wddoc.Tables(1).Range.Cells
With wdCell
ActiveSheet.Cells(.RowIndex, .ColumnIndex) = .Range.Text
End With
Next
You can handle different numbers of cells in each row, say from splits or merges, with something like this:
For m = 1 To wdDoc.Tables(1).Rows.Count
For l = 1 To wdDoc.Tables(1).Rows(m).Cells.Count
ActiveSheet.Cells(m, l) = wdDoc.Tables(1).Cell(m, l)
Next l
Next m
And then to clean things up a little
With wdDoc.Tables(1)
For m = 1 To .Rows.Count
For l = 1 To .Rows(m).Cells.Count
ActiveSheet.Cells(m, l) = .Cell(m, l)
Next l
Next m
End With
Hope that helps
i have a code that copies and rewrites anything thats between "(" and ")", but now i have different type of data which do not end with ")" so, i need it to stop when it reaches the last character in cell. Maybe it is dumb question but i cant seem to find how to fix my problem. I am a student and total newbie in vba (5 days ago i didn't know what vba is...) also sorry for my bad english.
I've tried to search (in here, google, youtube) but i couldnt find anything i need
'zaciatok=start koniec=end dlzka=length
Do While Mid(LookInHere, y, 1) <> ""
If Mid(LookInHere, Z, 1) = "(" Then
zaciatok = Z
End If
If Mid(LookInHere, y, 1) = ")" Then
koniec = y
dlzka = (koniec - 1) - zaciatok
dlzka = Abs(dlzka)
SplitCatcher = Mid(LookInHere, zaciatok + 1, CStr(dlzka))
MsgBox SplitCatcher
End If
y = y + 1
Z = Z + 1
Loop
In your specific implementation, one option is to modify your Do While ... loop to also test against the length of the string. That line would look something like:
Do While Mid(LookInHere, y, 1) <> "" And y < Len(LookInHere)
That modification tells the statement that it should terminate the loop when the iterating variable y goes past the length of the statement.
Another option is to change it from a Do While loop to a For loop. It would read something like:
For i = 1 to Len(LookInHere)
MsgBox Mid(LookInHere, i, 1)
'Input your logic here
Next i
The problem is that each of these versions is relatively inefficient, looping through each letter in a string a performing a calculation. Consider using built-in Excel functions. The Instr returns the position of a character, or a zero if it is not found. As an example, Instr("Abcdef", "b") would return the number 2, and Instr("Abcdef", "k") would return zero. You can replace the entire loop with these two function calls.
Z = Instr(LookInHere, "(")
y = Instr(LookInHere, ")")
If y = 0 Then y = Len(LookInHere)
Final note: if your patterns begin to get more and more complex, consider reviewing and implementing regular expressions.
You can use Right(LookInHere, 1) to get the last character of LookInHere
This is my Excel table with 3 input columns. The last column is the output column with the result I need.
Excel Input and Output data
Here is the sample macro I have:
Function month(x As string, y As string, z As String) As String
If (((x = "January.Winter") Or (y = "January.Winter")) And (z = "jan")) Then
month= "true"
Else If (((x = "January.2016") Or (y = "January.2016")) And (z = "jan")) Then
month= "true"
Else If (((x = "January.today") Or (y = "January.today")) And (z = "jan")) Then
month= "true"
Else
month= False
End If
End Function
My worksheet contains thousands of rows which includes "january" as a substring as a text in the cells. Instead of writing multiple checks like "if "x=January.winter"", I would like to use simplify the macro by checking if the string "x" or string "y" contains the string "January". Is there a way I could change the macro to do that?
Three ways that spring to mind:
If LCase$(x) Like "january*" Or LCase$(y) Like "january*" Then
...
If InStr(LCase$(x), "january") Or InStr(LCase$(x), "january") Then
...
If LCase$(Left$(x, 7)) = "january" Or LCase$(Left$(y, 7)) = "january" Then
...
It really just depends how inventive you want to get.
Note that I've used LCase$() to force text to lower case and prevent any issues with capitilisation - always something worth thinking about when comparing strings.
You can use the InStr function. Example use:
If (InStr(x,"January") > 0 Or InStr(y,"January")>0) And (z = "Jan") Then
...
It returns 0 if your substring isn't found, otherwise it returns the position of your substring.
More info here
Also careful with upper and lower casing. "January" will not match "january". Use LCase and UCase functions to force upper or lower casing, as Macro Man did in his answer.
I'm designing a function in VBA of the form myFunction(x,y,z) where z is a table, and x can take the values of the column headings. As part of the function I need to find the number of rows in z.
I'm having problems with this, as everywhere I look suggests using length = z.Rows.Count, but when I try and output this value (as in, set myFunction = length), it produces a VALUE error. However, when I output myFunction = a which doesn't directly use length (it will eventually form part of an IF statement once I get it working), the function works fine. My code is below:
Public Function myFunction(x As String, y As Double, z As Range) As Double
Dim upper_threshold As Double
Dim lower_threshold As Double
Dim a As Double
Dim rates As Variant
Dim u As Byte
Dim l As Byte
Dim r As Byte
Dim length As Byte
a = 0
u = 2
l = 1
rates = Application.WorksheetFunction.Index(z, 1, 0)
r = Application.WorksheetFunction.Match(x, rates, 0)
length = z.rows.Count
upper_threshold = z(u, 1)
Do While y > upper_threshold
u = u + 1
l = l + 1
upper_threshold = z(u, 1)
lower_threshold = z(l, 1)
If y < upper_threshold Then
a = a + z(l, r) * (y - lower_threshold)
Else
a = a + z(l, r) * (upper_threshold - lower_threshold)
End If
Loop
myFunction = a
End Function
To test it out I also created another function:
Public Function myRows(myTable As Range) As Double
myRows = myTable.rows.Count
End Function
This one works fine on its own, but when I try to use it within the other function, I still get a VALUE error. I've tried declaring length as every type I can think of and it doesn't seem to help.
Can anyone see what's going on?
EDIT: I'm obviously not making myself very clear. The function without the two lines referring to length works as I intended. However, I need to add a bit of code to increase its functionality and this involves calculating the number of rows in the table z. When I add the two lines shown here into the function it continues to work, since it doesn't affect the output. However, if I then set the output to show length, i.e. change the penultimate line to myFunction = length it gives me a VALUE error. This leaves me with two options as far as I can see: either something else in the program is impacting on these two lines (some clashes of syntax or something), or I'm making a mistake in just assuming I can output length like that.
Your problem is with:
rates = Application.WorksheetFunction.Index(z, 1, 0)
Index only accepts a single row or column, otherwise you get a VALUE error.