Excel VBA Command Button shows error for UserForm.Show - excel

This is the first time I'm asking a question on Stack Overflow so please forgive me if I'm not completely 100% clear in what my problem is.
A bit of context: I'm working on an automated Accounting system and I'm trying to add a UserForm to add new transactions to the General Ledger. I already achieved a Macro in Excel that generates Invoice in PDF Format and adds the data to the general ledger. Now I want to partly automise the process for incoming invoices by means of the UserForm.
The UserForm itself looks pretty need if I might say so myself. I'll try to add a picture to give an idea of what it looks like and what I get for input. I finished the entire coding of the UserForm, including the command for the command button, the UserForm_Initialize, and all the extra button coding needed to make it work.. So I thought. When I execute the code, it gives me several errors (amongst others, error 361 "Can't load or unload file"). The debug process shows that the error occurs in the "UserForm.Show" line of the command button.
The code that I have until now is as follows:
CommandButton
Private Sub CommandButton1_Click()
Load UserFormTransactions
UserFormTransactions.Show
End Sub
UserForm Initialize:
Private Sub UserForm_Initialize()
'Clearing Input boxes
Input_Type.Clear
Reference.Value = ""
Invoice_Date.Value = ""
PaymentTerm.Value = ""
VAT_Percent.Clear
Amount.Value = ""
Comment.Value = ""
Transaction_Type.Clear
Quarter1.Value = True
'Populate ComboBox - Input_Type
Dim rng As Range
Dim ws As Worksheet
Set ws = Worksheets("Types")
For Each rng In ws.Range("Type")
Me.Input_Type.AddItem rng
Next rng
'Populate ComboBox - VAT_Percent
Set ws = Worksheets("Types")
For Each rng In ws.Range("VAT_per_cent")
Me.VAT_Percent.AddItem rng
Next rng
'Populate ComboBox - Transaction_Type
Set ws = Worksheets("Types")
For Each rng In ws.Range("List_Transaction_Types")
Me.Transaction_Type.AddItem rng
Next rng
'Set Focus on Input_Type Box
Input_Type.SetFocus
End Sub
Add Transaction Button:
Private Sub Add_Click()
Dim LR As Long
Dim NR As Long
SheetName1 = "Transactions"
Worksheets(SheetName1).Activate
LR = Range("C:C").SpecialCells(xlCellTypeLastCell).Row
NR = Cells(LR, 3).End(xlUp).Row + 1
'Transfer Information
Cells(NR, 4).Value = Input_Type.Value
Cells(NR, 5).Value = Invoice_Date.Value
Cells(NR, 6).Value = PaymentTerm.Value
Cells(NR, 7).Value = Reference.Value
Cells(NR, 8).Value = Amount.Value
Cells(NR, 9).Value = VAT_Percent.Value
Cells(NR, 10).Value = Transaction_Type.Value
Cells(NR, 19).Value = Comment.Value
If Quarter1.Value = True Then Cells(NR, 3).Value = Quarter1.Caption
If Quarter2.Value = True Then Cells(NR, 3).Value = Quarter2.Caption
If Quarter3.Value = True Then Cells(NR, 3).Value = Quarter3.Caption
If Quarter4.Value = True Then Cells(NR, 3).Value = Quarter4.Caption
End Sub
Besides I have the coding for the Cancel and Clear button, but those are trivial and I expect there is no error in those. Anyone who could help me with this problem? All help is most appreciated.
Thanks,
Maarten

Related

UserForm doesnt work after unloading it and showing it again

Good Day People,
im kinda new to VBA.
Im trying to make a time and attandance.
Im actually pretty far, but unforntuanly i ran into a problem.
I use 2 Userforms. One where you get with your id to your sheet and can then clock in or clock out on the userform2.
When they clocked in or clocked it, it goes back to the first form. Unfornuatly the form doesnt work then anymore. I tried loading, hide, show, exit sub, searched the internet but cant find a solution.
Maybe im doing something wrong, that the modul / Userform doesnt work anymore.
Im thankfull for any help.
Dont mind Names of Strings and stuff, its just a test before i do the real one.
Im using the modulobject for the code. Looks better for me
So im refering in Userform1 Objects to a sub in the modullib.
Modul1:
Function DoesSheetExists(sh As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = ThisWorkbook.Sheets(sh)
On Error GoTo 0
If Not ws Is Nothing Then DoesSheetExists = True
End Function
Sub ScanID()
Dim MitarbeiterWS As Worksheet
Dim MitarbeiterID As Range
Dim MitarbeiterIDstring As String
Dim MitarbeiterName As String
ThisWorkbook.Sheets("MitarbeiterID").Activate
MitarbeiterIDstring = UserForm1.TextBox1.Value
Set MitarbeiterID = Range("A1:A30").Find(What:=MitarbeiterIDstring)
If Not MitarbeiterID Is Nothing Then
MitarbeiterName = MitarbeiterID.Offset(, 1).Value
UserForm1.Label1 = MitarbeiterName
If Not DoesSheetExists(MitarbeiterName) Then
If Not MitarbeiterName = "" Then
Sheets("Example").Copy After:=Sheets(Sheets.Count)
ActiveSheet.Name = MitarbeiterName
Unload UserForm1
UserForm2.Show
MitarbeiterID.Select
Else
End If
Else
ThisWorkbook.Sheets(MitarbeiterName).Activate
Unload UserForm1
UserForm2.Show
End If
Else
End If
End Sub
Modul2
Sub Eincloggen()
Dim Einspalte As Range
Set Einspalte = Range("A1").End(xlDown)
'wenn zum ersten mal eingeclockt
If Einspalte.Offset(, 1).Value = "" Then
If Einspalte.Value = "Clocked In" Then
Einspalte.Offset(1, 0).Value = Now
Else
MsgBox "Erst Raus"
End If
Else
Einspalte.Offset(1, 0).Value = Now
Unload UserForm2
UserForm2.Hide
UserForm1.Show
End If
End Sub
Sub Auscloggen()
Dim Einspalte As Range
Dim Ausspalte As Range
Dim Pausenspalte As Range
Dim Stundenspalte As Range
Set Einspalte = Range("A1").End(xlDown)
Set Ausspalte = Range("B1").End(xlDown)
Set Pausenspalte = Range("C1").End(xlDown)
Set Stundenspalte = Range("D1").End(xlDown)
If Ausspalte.Offset(1, -1).Value = "" Then
MsgBox "Erst Rein"
Else
Ausspalte.Offset(1, 0).Value = Now
If Not Ausspalte.Offset(1, 0).Value = "" Then
Stundenspalte.Offset(1, 0).Value = (Ausspalte.Offset(1, 0).Value) - (Einspalte.Value)
Stundenspalte.Offset(1, 0).NumberFormat = "hh:mm"
Unload UserForm2
UserForm2.Hide
UserForm1.Show
End If
End If
End Sub

Accept documents using MsgBox

I have most of the workings down and functional, there is one thing however that I am struggling to get my head around. What essentially happens is a person opens the form on an Excel sheet, fills it out and submits to the sheet.
At the bottom of the form there is an option to upload 2 documents, each is using its own button to display the file explorer. One of the forms MQF094 is always required, the second MQF095 is only required sometimes. Whenever they add a document to the form, the name of that document is displayed in a text box so the user can check that they have attached the right document before submitting to the sheet.
What I am trying to do is when a person clicks 'Submit' on the form a message box appears asking them if MQF095 is required, if they click no then the info is posted to the sheet as normal, if they click yes then they are prompted to add a form using the file explorer.
Currently if a person only adds MQF094 it works fine, however if they add both an MQF094 and MQF095 form, they are both posted to the sheet but in name only, there is no link to the actual document. This link however works just if only posting MQF094
The code for this is below. I can post my full code is necessary:
Dim TargetRow As Integer
Dim answer As Integer
TargetRow = Sheets("Backend").Range("K3").Value + 1
If MQF095Text.Value = "" Then
answer = MsgBox("Does an MQF095 form need to be added?", vbQuestion + vbYesNo, "MQF095 Query")
End If
If answer = vbYes Then
Sheets("Software Evaluation").Hyperlinks.Add Anchor:=Sheets("Software Evaluation").Range("Software_Start").Offset(TargetRow, 6), Address:=stpPath _
, TextToDisplay:=MQF095Text.Value
Else: answer = vbNo
Sheets("Software Evaluation").Hyperlinks.Add Anchor:=Sheets("Software Evaluation").Range("Software_Start").Offset(TargetRow, 5), Address:=strPath _
, TextToDisplay:=MQF094Text.Value
With Sheets("Software Evaluation").Range("Software_Start")
.Offset(TargetRow, 1).Value = SoftwareNam
.Offset(TargetRow, 2).Value = SupplierName
.Offset(TargetRow, 3).Value = PrincipalApp
.Offset(TargetRow, 4).Value = TypeCombo
.Offset(TargetRow, 5).Value = MQF094Text
.Offset(TargetRow, 6).Value = MQF095Text
End With
End If
MsgBox "Software Entry Added Successfully", vbOKOnly, "Software Added"
Try if this is the correct logic
Private Sub CommandButton1_Click()
Dim TargetRow As Integer, answer As Integer
Dim ws As Worksheet, rng As Range
' test values
Const strPath = "C:\" ' MQF094 file
Const stpPath = "C:\" ' MQF095 file
Set ws = Sheets("Software Evaluation")
Set rng = ws.Range("Software_Start")
TargetRow = Sheets("Backend").Range("K3").Value + 1
If MQF095Text.Value = "" Then
answer = MsgBox("Does an MQF095 form need to be added?", vbQuestion + vbYesNo, "MQF095 Query")
End If
With rng
.Offset(TargetRow, 1).Value = SoftwareNam
.Offset(TargetRow, 2).Value = SupplierName
.Offset(TargetRow, 3).Value = PrincipalApp
.Offset(TargetRow, 4).Value = TypeCombo
ws.Hyperlinks.Add Anchor:=.Offset(TargetRow, 5), _
Address:=strPath, TextToDisplay:=MQF094Text.Value
If answer = vbYes Then
ws.Hyperlinks.Add Anchor:=.Offset(TargetRow, 6), _
Address:=stpPath, TextToDisplay:=""
Else
.Offset(TargetRow, 6).Value = MQF095Text.Value
End If
End With
MsgBox "Software Entry Added Successfully", vbOKOnly, "Software Added"
End Sub

Change label's caption with loop in a VBA userForm

I want my code to loop through a range of cells and every time show the content of the cell (that is a question) in a label's caption of a userForm and allow the user to choose the button of "Yes" (for knowing the answer) or "NO" (for not knowing the answer) and then the code use the user's response to perform some actions and then continue the loop for other cells.
For each iteration in for loop i need user be allowed to choose "Yes" or "No" or "Cancel" and then the userForms code continue running.
Here is some of the code:
Private Sub UserForm_Activate()
For i = 2 To n
Cells(i, 3) = Cells(i, 3) + 1
If Cells(i, 3) = 1 Then
UserForm1.Controls("question").Caption = Cells(i, 1).Value 'lable 1
UserForm1.Controls("answer").Caption = "" 'lable 2
'some codes...
elseIf Cells(i, 3) = 3 Then
UserForm1.Controls("question").Caption = Cells(i, 1).Value 'lable 1
UserForm1.Controls("answer").Caption = "" 'lable 2
next
end sub
and i need to run these codes whenever user clicks on a button on the form . then the rest of the above code be executed .
Private Sub ansYes_Click() 'If user clicks Yes show the answer and continue
UserForm1.Controls("answer").Caption = Cells(i, 2)
UserForm1.Controls("answer").Visible = True
End Sub
Private Sub ansNo_Click() 'If user clicks No show the answer and continue
UserForm1.Controls("answer").Caption = Cells(i, 2)
UserForm1.Controls("answer").Visible = True
Cells(i, 3) = 0
Cells(i, 4) = 1
End Sub
Private Sub ansCancel_Click() 'If user clicks cancel unload userform and exit the for loop
Unload UserForm1
End Sub
You haven't shown us where you show the UserForm or how it is defined within your project and you haven't given a good description of the problem. This forces assumptions that may not be accurate.
Do not name your UserForm "UserForm1", give it a useful name. Henceforth, I will refer to this as "UserResponseForm"
Do not use default instance of a UserForm, use a variable and learn the difference between Dim As and Dim As New. The difference is significant and important.
Dim myForm As UserResponseForm
Dim myForm As New UserResponseForm
Using UserResponseForm's property window, find and rename your labels "Question" and "Answer"
In UserResponseForm's code use Ctrl + H to replace:
UserForm1.Controls("answer") with Me.Answer
and
Unload UserForm1 with Me.Hide
Move all of your code from Private Sub UserForm_Activate to a normal module. Give the module and the sub a useful name. I will refer to module as "QuestionaireCodeModule" and the sub as "RunTheQuestionnaire"
The QuestionaireCodeModule should look similar to this
Option Explicit
Private Const n As Long = 20 'you didn't show how n was populated or scoped so I put it here
Sub RunTheQuestionaire()
Dim i As Long
Dim myForm As New UserResponseForm
For i = 2 To n
Cells(i, 3) = Cells(i, 3) + 1
If Cells(i, 3) = 1 Or Cells(i, 3) = 3 Then 'added or condition for clarity
myForm.Question.Caption = Cells(i, 1).Value 'lable 1
myForm.Answer.Caption = vbNullString 'lable 2
'some codes...
'next three lines removed because they are redundant
'elseIf Cells(i, 3) = 3 Then
'UserForm1.Controls("question").Caption = Cells(i, 1).Value 'lable 1
'UserForm1.Controls("answer").Caption = "" 'lable 2
End If
myForm.Show
If Not myForm.Visible Then Exit For
Next i
End Sub
That should be it but I can't say if this will work for you or not because you did not provide enough to work with and the code you provided in your example won't compile.

Runtime Error 13 - Mismatch

I'm new at VBA coding and working on a match code. The code is working just fine when I run the code in "Data sheet" (the sheet were all my data is and were the match has to be found), but when i'm run the code on the frontpage (Sheet 1 with userforms) the code is debuggen and says "Runtime Error 13". Can anybody tell what the problem is?
And can anybody tell me why my "If isError" doesn't work?
Thanks in advance!
Br
'Find SKU and Test number
Dim icol As Integer
Sheet13.Range("XFD2") = UserForm2.ComboBox1.Value 'Sættes = ComboBox1.value
Sheet13.Range("XFD3") = UserForm2.ComboBox2.Value 'Sættes = ComboBox2.value
icol = [Sheet13.MATCH(XFD2&XFD3,A:A&Q:Q,0)] 'Match af værdien for vores SKU og test nr
With ThisWorkbook.Worksheets("Data sheet")
'If SKU or Test number not found, then messagebox
If IsError("A:A") Then MsgBox "SKU not found": Exit Sub
If IsError("Q:Q") Then MsgBox "Test number not found": Exit Sub
'Add test result/next step and comment
.Cells(icol, 30).Value = Me.ComboBox3.Value
.Cells(icol, 30 + 1).Value = Me.Comments_To_Result.Value
End With
End If
Set objFSO = Nothing
Set openDialog = Nothing
Range("XFD2").Clear
Range("XFD3").Clear
icol should be like this:
icol = Application.match(arg1, arg2, arg3)
See the samples in MSDN:
var = Application.Match(Cells(iRow, 1).Value, Worksheets(iSheet).Columns(1), 0)
Concerning If IsError("A:A") Then MsgBox "SKU not found": Exit Sub, you are doing it wrongly. I assume, that you want to loop through all the cells in the first column and to get whether one of them is an error. You need a loop for this. This is a really simple one, but you should implement it somehow in your code:
Option Explicit
Public Sub TestMe()
Dim rng As Range
For Each rng In Range("A:A")
If IsError(rng) Then Debug.Print rng.Address
Next rng
End Sub

Run sub procedure in excel after values passed from MS Access record

I have an Access database which successfully passes the values in my current record to an Excel sheet. To calculate my Excel sheet I then need to call a subroutine.
I think my problem is the order in which things are happening.
I have tried to call the routine (within Excel) from the MyWorkbook with the following code
Private Sub Workbook_Activate()
On Error Resume Next
With Application
.DisplayFullScreen = True
.CommandBars("Worksheet Menu Bar").Enabled = True
.ScreenUpdating = False
End With
Call Rategenerator
Sheets("home").Select
End Sub
The routine Rategenerator is, I think, being called before the values from the Access record are populating the designated cells in my sheet "home."
Is there a way to force the sub routine Rategenerator to execute after the values are populated on the sheet?
The code from the current Access record to populate the Excel sheet looks like this:
Dim objXLApp As Object
Dim objXLBook As Object
Dim r As Object
'check whether Excel is open before opening another copy.
Set objXLApp = CreateObject("Excel.Application")
Set objXLBook = objXLApp.Workbooks.Open("e:\!!!Access SHare Folder\Ogden v7.1.1.5 final.xls")
objXLApp.Application.Visible = True
'Specify Sheet
With objXLBook.Sheets("home")
.unProtect Password:="xxxxxxxx"
.Cells(15, 6).Value = Me.DateofAcc
.Cells(16, 6).Value = Me.DOB
.Cells(17, 6).Value = Me.todaysDate
.Cells(18, 6).Value = Me.Gender
.Cells(19, 6).Value = Me.RetireAge
.Cells(22, 6).Value = Me.DeferredAge
.Cells(28, 6).Value = Me.ContEmpPre
.Cells(29, 6).Value = Me.ContDisPre
.Cells(30, 6).Value = Me.txtContOveridePre 'taken from the txtbox not the checkbox
.Cells(31, 6).Value = Me.ContOverideValPre
.Cells(28, 7).Value = Me.ContEmpPost
.Cells(29, 7).Value = Me.ContDisPost
.Cells(30, 7).Value = Me.txtContOveridePost 'taken from the txtbox not the checkbox
.Cells(31, 7).Value = Me.ContOverideValPost
End With
With objXLBook.Sheets("LOETblCalx")
.Cells(19, 17).Value = Me.SalaryNet1
.Cells(20, 17).Value = Me.Residual1
End With
''Tidy up
Set objXLBook = Nothing
Set objXLApp = Nothing
End Sub
As I say all the field values from the Access record populate without issue. Parts of the Excel workbook which do not rely on the sub routine auto calculate as expected with Auto calculation in the workbook turned on.
Its just the triggering of the sub routine after the cells have been populated which is causing me some difficulty.
Eventually I want to try and get the calculated results back into some additional fields in the Access record but having never attempted anything like that before I'm careful not to get ahead of myself.
Thanks for looking
Instead of using Workbook_Activate(), try running the Excel macro directly from your Access code after it has finished populating. This would be done by putting code similar to this at the end (before the tidy up part) of your Access macro: objXLBook.Run "Rategenerator"
I'm not sure if that exact piece of code will work for you, but see here for more details on how to do it.

Resources