How do I solve Application.Worksheetfunction.Match error? - excel

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

Related

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

Excel VBA Command Button shows error for UserForm.Show

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

Excel VBA To Process and Forward Emails Causing "Out of memory" Error

I hope someone can help- I'm hitting the dreaded "Out of memory or system resources" error with some code running in Excel and working with Outlook; from which the error originates.
Short description is it runs through a list of emails looking in the body/subject for a reference. If it finds it, it forwards the email item with the reference in the subject. MWE below; I'm not very experienced handling Outlook objects but I've spent nearly two hours trying different things with no luck. I can't use the GetTable() function since it doesn't include Body text data as far as I know (working off this), unless you can somehow add columns to include the body text?
If I run it in a freshly-opened Outlook session with only a dozen items it isn't a problem but I need it to work on hundreds of emails in one pop. Banging my head against a wall here. Thanks so much in advance!
Private Sub processMWE(ByVal oParent As Outlook.MAPIFolder)
Dim thisMail As Outlook.MailItem
Dim myItems As Outlook.Items
Dim emailindex As Integer
Dim folderpath As String
Dim refandType As Variant
Dim fwdItem
Set myItems = oParent.Items
folderpath = oParent.folderpath
'Starting at row 2 on the current sheet
i = 2
With myItems
'Data output to columns in Excel
For emailindex = 1 To .Count
Set thisMail = .Item(emailindex)
'i takes row value
Cells(i, 1).Value = folderpath
Cells(i, 2).Value = thisMail.Subject + " " + thisMail.Body
Cells(i, 3).Value = thisMail.SenderEmailAddress
Cells(i, 4).Value = thisMail.ReceivedTime
Cells(i, 6).Value = thisMail.Categories
'Reference from body/subject and a match type (integer)
refandType = extractInfo(Cells(i, 2))
'This is the reference
Cells(i, 5).Value = refandType(0)
'And this is the match type.
Select Case refandType(1)
Case 1, 2
'do nothing
Case Else
'For these match types, fwd the message
Set fwdItem = thisMail.Forward
fwdItem.Recipients.Add "#########"
fwdItem.Subject = Cells(i, 5) & " - " & thisMail.Subject
fwdItem.Send
'Edit original message category label
thisMail.Categories = "Forwarded"
thisMail.Save
'Note in spreadsheet
Cells(i, 7).Value = "Forwarded"
End If
End Select
i = i + 1
Next
End With
End Sub
Edit: New development: not only is it always hanging on the same line of code (thisMail.Body) it's actually doing it for specific mail items?! If I give it a batch of one of these problem messages it hangs immediately. Could it be something to do with character encoding or message length? Something that means thisMail.Body won't work that triggers a resources error?
Reason of the problem:
You are creating items without releasing them from memory -with these lines-
For emailindex = 1 To .Count
Set thisMail = .Item(emailindex)
Solution
Release the objects once you are done with them
End Select
i = i + 1
Set thisMail = Nothing
Next
End With
Common language explanation
In this scenario, think about VBA as a waiter, you are telling it that you are going to give some dishes to serve to the customers, you are giving all of them to it, but you never tell it to release them to the table, at one point, it will not be able to handle any more dishes ("Out of memory")

check if IsNumeric using Me.Controls()

I have a userform with dozens of text boxes where the user should input only numbers from 1 to 6. When the form is completed the user clicks Save and the numbers are added to an Excel table.
As the text boxes are quite a lot I used the following code to read their value:
' Text boxes name are: txt_a01, txt_a02, txt_a03...
For i = 1 To 5
ws.Cells(iRow, i).Value = Me.Controls("txt_a0" & i).Value
Next
' Here text boxes name are: txt_b01, txt_b02, txt_b03...
For i = 6 To 10
ws.Cells(iRow, i).Value = Me.Controls("txt_b0" & i - 5).Value
Next
etc.
rather than write dozens of times:
ws.Cells(iRow, 1).Value = Me.txt_a01.Value
ws.Cells(iRow, 2).Value = Me.txt_a02.Value
ws.Cells(iRow, 3).Value = Me.txt_a03.Value
ws.Cells(iRow, 4).Value = Me.txt_a04.Value
ws.Cells(iRow, 5).Value = Me.txt_a05.Value
Now I would like to check - during input - if the user has really added a number and if its between 1 and 6. Normally I would do it like this:
Private Sub txt_a01_AfterUpdate()
If Not IsNumeric(txt_a01.Value) Then
MsgBox ("Only numbers accepted")
End If
End Sub
But as I use a FOR - LOOP and Me.Controls() to read the text box values I don't understand how to write down the _AfterUpdate Sub.
You could attach dynamically an event handler on form load or you could create a custom control with an event.
Personally I prefer use custom control and KeyPressEventHandler to refuse all not allowed chars.
You may create a class to handle the event :
Private WithEvents m_oTextBox as TextBox
Public Property Set TextBox(ByVal oTextBox as TextBox)
Set m_oTextBox = oTextBox
End Property
Private Sub m_oTextBox_Change()
' Do something
End Sub
then, for each control:
Dim myEventHandler As TextBoxEventHandler
Set myEventHandler = New TextBoxEventHandler
Set myEventHandler.TextBox = oControl
m_oCollectionOfEventHandlers.Add myEventHandler

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