I am totally new to VBA. I use it maybe once a year and when I do I search this and other forums for code. For my humble needs, that usually works perfectly. Unfortunately due to my lack of real understanding of the code, in this case I am unable to see what I`m doing wrong. So hopefully somebody can help.
I have a timesheet where I want to copy the values to a datasheet. I have that working. But it is important that the users fill-out the right weeknumber in the form. In order to check if they have done that, I have written a piece of code that should return a messagebox when the weeknumber is not filled. When I simply use a reference to a single cell the code works. But as the weeknumber is not filled in in the same cell on all forms I want the macro to search for the text "Weeknumber: " and then check if the cell next to it is empty or not.
Sub Weeknumber()
dim cl as Range
Worksheets("Invul_Tabel").Activate
With Worksheets("Invul_Tabel").Cells
Set cl = .Find("Weeknummer:", After:=.Range("A1"), LookIn:=xlValues)
If IsEmpty(Range(cl).Offset(0, 1).Value) = True Then
MsgBox "Geen weeknummer ingevuld"
Exit Sub
End If
End With
End Sub
The code gives an error on the "If IsEmpty" line" (error 1004).
Is probably simple, but i can`t seem to figure it out!
Your cl variable is already a range.
Change
If IsEmpty(Range(cl).Offset(0, 1).Value) = True Then
to
If IsEmpty(cl.Offset(0, 1).Value) Then
Related
First time poster in StackOverflow (but not stackexchange) so please let me know if I can clarify or make any formatting changes. Thank you.
Try as I might, I can't find the answer to this question. I suspect it's due to a lack of understanding when it comes to the basics of VBA. I have knowledge of VBA, but little understanding. That being said, here's the problem.
I've set up a form control Combo Box linked to a macro. I've set the input range to a list of hyperlinks in a different sheet and named the range "Hyperlinks". Each hyperlink is to a different sheet in the workbook. I've set the cell link to a blank sell adjacent to the hyperlinks and named it "Linked_Cell." A picture is below.
Form Control View
The macro code is as follows
Sub DropDown10_Change()
HyperLink_Index = Range("Linked_cell")
If Range("HyperLinks").Offset(HyperLink_Index - 1, 0).Hyperlinks(1).Name <> "" Then
Range("HyperLinks").Offset(HyperLink_Index - 1, 0).Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True
End If
End Sub
This automatically moves someone to the sheet they select when they select that sheet from the drop-down menu.
I would like to use an Active X combo box instead of a form control for all the obvious reasons (resize text, etc.) However, I can't get it to work.
I've set "ListFillRange" to "Hyperlinks" and linked cell to "Linked_cell" and entered the same macro code. It looks like this:
View of Active X Combo Box
When I select from the drop down in the Active X Combo box I receive run time error 1004: "Method 'range' of object '_worksheet' failed." I've verified that my named ranges are correct and the code returns no such error when it's in a macro linked to a form control.
Any help is much appreciated! Thank you!
UPDATE: Fixed the Range error by updating the code to the following
Sub ComboBox1_Change()
Dim HyperLink_Index As Range
Set HyperLink_Index = Sheets("SheetList").Range("Linked_Cell")
If Sheets("SheetList").Range("HyperLinks").Offset(HyperLink_Index - 1, 0).Hyperlinks(1).Name <> "" Then
Sheets("SheetList").Range("HyperLinks").Offset(HyperLink_Index - 1, 0).Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True
End If
End Sub
I now receive a Type Mismatch error on the beginning of the IF statement. I don't see the error and still have no idea why this behavior doesn't appear for identical macro code linked to a form control.
P.S. Sorry, I don't mean to turn StackOverflow in to my personal debugging team, so the main question I have is "Why is the behavior different between a macro and active x code?"
UPDATE 2: Found a fix. Was using the wrong index. The fix is below. Leaving it here in case someone else can find it useful.
Sub ComboBox1_Change()
If ComboBox1.Value <> "" Then
Sheets("SheetList").Range("Hyperlinks").Hyperlinks(ComboBox1.ListIndex + 1).Follow NewWindow:=False, AddHistory:=True
End If
End Sub
Found a fix. Was using the wrong index. The fix is below. Leaving it here in case someone else can find it useful.
Sub ComboBox1_Change()
If ComboBox1.Value <> "" Then
Sheets("SheetList").Range("Hyperlinks").Hyperlinks(ComboBox1.ListIndex +1).Follow NewWindow:=False, AddHistory:=True
End If
End Sub
(I know this sounds like a repeat question, but I've searched everywhere for this, and I couldn't find anything about this)
I'm trying to automate a tax filing process at work. Essentially, I'm reading off several worksheets and populating relevant fields into a master mapping sheet. However (and this is the strange part), when I first coded everything out, there were no errors and I managed to find everything. After saving and reopening the workbook though, I keep getting this error and only for certain lines (9 occurences out of the 57 times I call the .find method in total).
I know the error means that the .find method couldn't find what I was looking for, but I know the field exists since it worked perfectly well before I closed and reopened the workbook, and it works for the rest of the searches. Does anyone have any ideas?
I've checked my macro security settings (everything is enabled), and I know the .find method isn't retrieving anything (I put in "if ___ is nothing" statements to verify, and the affected lines all return nothing when called), but I know the fields I'm searching for exist in their respective sheets.
Here's one of the lines throwing the error:
Range("C7").Select
Set currentRowReference = Worksheets("Stat A").Range("B1:B999").Find("Current year tax losses", LookIn:=xlValues, lookat:=xlPart)
firstCalculation = Worksheets("Stat A").Cells(currentRowReference.Row - 2, "E")
Set currentRowReference = Worksheets("Stat A").Range("A1:A999").Find("Unabsorbed capital allowances c/f", LookIn:=xlValues, lookat:=xlPart)
secondCalculation = Worksheets("Stat A").Cells(currentRowReference.Row - 1, "E")
ActiveCell.FormulaR1C1 = firstCalculation - secondCalculation
Any help or ideas will be much appreciated!
Edit: I've added a larger portion of my code, and a screenshot of the sheet it's supposed to read from. In the code above, firstCalculation successfully computes, while secondCalculation throws the error.
Screenshot of source sheet. Specifically, it's supposed to read A31
since you have to deal with merged cells, you'd better use a function on your own like the following:
Function MyRowFind(rng As Range, textToFind As String) As Long
Dim cell As Range
MyRowFind = -1
For Each cell In rng.SpecialCells(xlCellTypeConstants, xlTextValues)
If InStr(cell.value, textToFind) > 0 Then
MyRowFind = cell.Row
Exit Function
End If
Next cell
End Function
to be used in your main sub as follows:
Sub main()
Dim currentRowReferenceRow As Long
currentRowReferenceRow = MyRowFind(Worksheets("Stat A").Range("A1:A999"), "Unabsorbed capital allowances c/f")
If currentRowReferenceRow > 0 Then
' code
End If
End Sub
i am working on a userform where i puted a button that when i click on it i got an input box where i try to filter data of the column (E) then after filtering this data copy from colum A1 till the value filtered in the column E in another sheet caaled filtred_data i am using this code this code but it show me a bug dont nw how to fix it
Private Sub CommandButton9_Click()
Dim xno As Integer, Found As Range
Do
xno = Application.InputBox("Enter the number of Top communities ", Type:=1)
If TypeName(xno) = "Boolean" Then Exit Sub
Set Found = Columns("E").Find(what:=xno, lookat:=xlWhole, LookIn:=xlValues)
If Found Is Nothing Then
MsgBox "the number was not found, please try again !!", vbInformation
Else
Found.Range("A1:F10000").Copy Destination:=Sheets("filtred_data").Range("A1:F10000")
End If
Loop
End Sub
if anyone can help me please , thank you
The problem in your case is that you are setting the Found variable to be a single cell by using the Find method. Later in your code, you are trying to copy the A1:F10000 of that ONE cell when you write Found.Range("A1:F1000").
Essentially, your code looks like this (assume Found refers to cell E25):
Range("E25").Range("A1:F1000").Copy
Can you see why that would cause an error?
I'd try to offer more help, but it's hard to determine exactly what you want. Can you possibly give more details about your spreadsheet layouts and an example of what you want to happen?
I'm doing some work on an already done excel program, but I'm very rusty in this area or probably never had done something in this part, I'm very new in VBA so please don't judge me if it's a simple mistake or error the links are in the description.
So I have problem where if I put the confirmation option, for example: in one cell press "1" in the product you have, and in another cell write "S" if you already have the product and it puts you a date of today in another cell.
The problem is when I delete the info that I inserted, and reenter it the date deformats itself becoming smaller and the location on the cell changes too.
I'm going to put the links because, like I said I'm rusty and I can't find where the code of this date comes.
http://www.docdroid.net/12dh4/master-atual-20155.xls.html -->This one is the Excel
http://www.docdroid.net/12dhj/errorphotos.pdf.html --> photos showing error
this is the code of one of the sheets the other ones are almost the same, If you guys see the photos it would help to understand the error itself.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng1 As Range
Set rng1 = Intersect(Range("v3:v500"), Target)
If rng1 Is Nothing Then Exit Sub
Application.EnableEvents = False
On Error Resume Next
If rng1.Value <> "" Then
rng1.Offset(0, 2).Value = Now()
Else
rng1.Offset(0, 2).Clear
End If
Application.EnableEvents = True
End Sub
The code would be triggered when you do the changes at column V. You may find the code in the worksheet itself:
it will clear the date if the column V contains no value.
By the way, the date is not getting smaller but it show the date of today in different format. you may check the date format by right click the cell and choose the format cells... option to look at it.
I cannot figure out the best way to do the following problem. Basically my macro (excel, VB) is checking several (100+) worksheets for correct values, if wrong value is found, I want it to stop, give me a warning, then I could have a look into the reason why the value is wrong, correct it manually and then I want to resume the macro, or remember the last value checked so if I return, it remembers where to continue (resume).
My current problem is that it finds the wrong value, then I can either make it stop so I check the problem, or it goes through all the sheets and then I have to remember which sheets had the wrong value.
What I thought of is make a list where the name of sheet is added every time a wrong value is found. The problem is that usually there is more than 1 wrong value in the same sheet if there is a wrong value at all and this added the same sheet name several times to the list. Another problem with that is that I cannot correct the values straight away.
I'm very inexperienced with programming and so would appreciate your idea on how to best approach this problem (I don't want to spend a long time on coding something which wouldn't be efficient for such a "simple" problem).
When the error is found (I'm assuming you've already been able to identify this), you can use the Application.InputBox function to prompt you for a new value.
For example, if rng is a Range variable that represents the cell being checked, and you have some logic to determine where the error happens, then you can just do:
rng.Value = Application.InputBox("Please update the value in " & rng.Address, "Error!", rng.Value)
The inputbox function effectively halts execution of the procedure, while waiting for input from the user.
If InputBox isn't robust enough, then you can create a custom UserForm to do the same sort of thing. But for modifying single range values, one at a time, the InputBox is probably the easiest to implement.
I believe you can handle this task by using one or two static local variables in your macro. A variable declared with "static" rather than "dim" will remember its value from the last time that procedure was run. This can hold where you left off so you can resume from there.
One thing that could be a problem with this solution would be if the macro gets recompiled. That would probably cause VBA to clear the value that the static variable was holding. Just doing a data edit in Excel should not cause a recompile, but you will want to watch for this case, just to make sure it doesn't come up. It almost certainly will if you edit any code between executions.
Create a public variable that stores the cell address of the last checked cell and use a conditional statement to see if it's "mid-macro" for want of a better phrase. here is a very crude example...
Public lastCellChecked As String
Sub Check_Someting()
Dim cell As Excel.Range
Dim WS As Excel.Worksheet
If Not lastCellChecked = vbNullString Then Set cell = Evaluate(lastCellChecked)
'// Rest of code...
'// Some loop here I'm assuming...
lastCellChecked = "'" & WS.Name & "'!" & cell.Address
If cell.Value > 10 Then Exit Sub '// Lets assume this is classed as an error
'// Rest of loop here...
lastCellChecked = vbNullString
End Sub
The best way to do this is to create a userform and as mentioned by prior users create a public variable. When the program finds an error store the cell and initiate the userform. Your code will stop on the userform. When you're done checking the problem have a button on the userform that you can click to continue checking. Your loop can be something like the below.
public y as integer
sub temp1 ()
rw1= range("a500000").end(xlup).row 'any method to create a range will do
if y = null then y=1
for x = y to rw1
cells(x,1).select
'check for the problem your looking for
if errorX=true then
userform1.show
y = activecell.row
exit sub
end if
next x
end sub
What about inserting a button (on the sheet or in a menubar) for stopping?
Insert the code below:
'This at the top of the module
Public mStop As Boolean
'This in the module
Sub MyBreak()
mStop = True
End Sub
'This is your macro
Sub YourMacro()
'This at the top of your code
mStop = False
'Your code
'...
'This code where you want to break
DoEvents '<<<< This makes possible the stop
If mStop Then
mCont = MsgBox("Do you want to continue?", vbYesNo)
If mCont = vbNo Then
Exit Sub
Else
mStop = False
End If
End If
'Your code
'...
End Sub
Now you need to create a button and link it to the macro called "MyBreak".