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
Related
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
I currently have a macro that works amazing well in Excel, but I'm wanting to add a Yes/No question into the VBA prior to starting the macro. The problem is I've tried several methods and looked for a way to make this work, and adding a simple one-line conditional statement isn't enough for what I'm trying to do.
Essentially, if the user selects Yes, I need the current macro to run in its entirety, but if they select No, I need a message box to popup stating they will need to complete the verification steps to continue. The current code (without any yes/no statement) is as follows... can anyone help?
Sub Submit_Details()
Dim shDrug As Worksheet
Dim shLogging As Worksheet
Dim iCurrentRow As Integer
Dim sDrugName As String
Set shLogging = ThisWorkbook.Sheets("Logging")
sDrugName = shLogging.Range("G11").Value
Set shDrug = ThisWorkbook.Sheets(sDrugName)
iCurrentRow = shDrug.Range("A" & Application.Rows.count).End(xlUp).Row + 1
With shDrug
.Cells(iCurrentRow, 1) = Format([now()], "DD-MMM-YYYY HH:MM:SS")
.Cells(iCurrentRow, 2) = shLogging.Range("G7")
.Cells(iCurrentRow, 3) = shLogging.Range("G8")
.Cells(iCurrentRow, 4) = shLogging.Range("G9")
.Cells(iCurrentRow, 5) = shLogging.Range("G10")
.Cells(iCurrentRow, 6) = shLogging.Range("G12")
.Cells(iCurrentRow, 7) = shLogging.Range("G13")
End With
shLogging.Range("G7, G8, G9, G10, G11, G12, G13").Value = ""
MsgBox "Data submitted successfully!"
End Sub
If you put this snippet first in the sub, it will get you started:
If MsgBox("Are you sure?", vbYesNo) <> vbYes Then
Exit Sub
End If
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.
I searched net for answer but nothing worked (found 5-6~ different solutions but neither worked for me.
I'm getting 1004 error for Application Match. What it does in my case it should give a range from Data sheet to Column E_Menu - "menu" so I could choose one entry from a list of already created and edit it, but for some reason it won't work.
I tried defining column E_menu, changing variants for Range ("xxxxx") which originaly was Dyn_Full_Name or smth but it wouldnt work either.
Option Explicit
Private Sub CommandButton1_Click()
Dim TargetRow As Integer
```TargetRow = Application.WorksheetFunction.Match(ColumnE_Menu, Sheets("Data").Range(Cell1:="B2", Cell2:="D4"), 0)```
Sheets("Engine").Range("B5").Value = TargetRow for use later
Unload Find_Entry_UF
'''Begin retrieving data from database'''
Data_UF.Txt_Update = Sheets("Data").Range("Data_Start").Offset(TargetRow, 2).Value 'first name
Data_UF.Txt_Description = Sheets("Data").Range("Data_Start").Offset(TargetRow, 3).Value 'surname
Data_UF.Txt_Owner = Sheets("Data").Range("Data_Start").Offset(TargetRow, 4).Value 'age
Data_UF.Txt_Proc = Sheets("Data").Range("Data_Start").Offset(TargetRow, 6).Value 'gender combo box
Data_UF.Combo_Status = Sheets("Data").Range("Data_Start").Offset(TargetRow, 7).Value 'region combo box
'''End retrieving data from database'''
Data_UF.Caption = "Edit Existing" 'set caption to show that the user is editing
Data_UF.Show 'show the user form with the details loaded in
End Sub
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.