Referring to subform record in access - excel

I have the following form, with three subforms:
The button on the top right opens a userform in excel. I would like that userform to already have some of the selected values from these subforms. However, I am unable to refer to the records in the subforms in my VBA code. I've been successful in transferring the values from the main form, such as name etc. but not the ones from the subform. Code in access:
Option Compare Database
Private Sub Toggle159_Click()
Dim abc As String
abc = Me.CompanyName
Dim xlApp As Object 'Excel.Application, xlWB As Excel.Workbook
Dim xlWB As Object
Set xlApp = CreateObject("Excel.Application")
Set xlWB = xlApp.Workbooks.Open("C:\NA\eb\quotegenv2.xlsm") ' specify file
xlApp.Visible = True
xlApp.Run "Module3.showFormWithValues", abc
End Sub
In the above code, CompanyName is a control on the mainform. This code runs fine but I've tried to refer to items in the subform using 'me.subformname.form.controlname' but the control name does not appear in the suggestions.
Code in excel for the module:
' placed in code Module3
Sub showFormWithValues(txt1 As String)
With UserForm1
.ClientName.Text = txt1
End With
UserForm1.Show
End Sub
Any help is appreciated.

You have tried to set ClientName before the form is open.
Use a global variable at the top of module 3 to share the data between showFormWithValues and the form.
At the top of Module3 before the first procedure as a public variable as the example below shows: -
Option Explicit
Public StrCN As String
Sub showFormWithValues(txt1 As String)
...
End Eub
In UserForm1 add (or update if it already exists) the following: -
Private Sub UserForm_Activate()
Me.ClientName.Text = Module3.StrCN
End Sub

Related

Open/Close Workbook in Userform

In a Userform I want to open another workbook (than the active one)
Part of my code:
Private Sub cmbKontoPos1_Change()
Workbooks.Open Filename:=filename1
'Here should of course be some code, but it is not now
Workbooks(filename1).Close SaveChanges:=False
Open-command works.
But the Close-command gives error:
Error no '9'
Index out of bounds
(I get the error-message in Swedish, hope I translate correct)
What is it I do not understand?
Quick fix is to have a global Workbook Variable so you can assign it on Open and use it on other UserForm Events, the example below has two Buttons and one opens while the other one closes the Workbook. Tested and working.
You can see the Dim secondWorkbook outside the UserForm buttons this is to make it global. On the first button I assign the Opened workbook to that Variable and i can close it later.
Dim secondWorkbook As Workbook
Private Sub CommandButton1_Click()
'Open WB
Dim filename1 As String
filename1 = "F:\WorkbookPath\WBName.xlsx"
Set secondWorkbook = Workbooks.Open(filename1)
End Sub
Private Sub CommandButton2_Click()
'Close WB
secondWorkbook.Close False
End Sub
You can also use this variable to make changes to the workbook like: secondWorkbook.Worksheets(1).Range("A1").Value = "Test" as long as it is still open of course.

Excel: pass workbook object from sub to userform

I want to pass two objects (one open workbook and other a table) from sub procedure to userform. I have made both of them global before the sub.
When I write just the two public declarations before Sub (they are set inside Sub),works good within Sub but when the userform initializes, it throws the error "Object variable or with block variable not set"
Public N As Workbook
Public E As ListObject
Sub...
I tried to set these two objects before Sub, the Sub doesn't run, throws compile error, "Invalid outside procedure"
Public N As Workbook
Set N = Workbooks.Open(ThisWorkbook.Sheets("New").Range("A1").Text)
Public E As ListObject
Set E = N.Sheets(1).ListObjects(1)
Sub...
How to pass object variables from Sub procedures to Userforms? Currently the only solution I see is to set the objects in both the Sub procedure and the Userform.
Add a Sub to your UserForm to set your Workbook and ListObject objects.
Userform:
Private pWB As Workbook
Private pLO As ListObject
Public Sub SetObjects(ByVal wb As Workbook, ByVal lo As ListObject)
Set pWB = wb
Set pLO = lo
End Sub
In your calling code:
Sub CallingCode()
Dim UF As UserForm1 ' Don't use the global UserForm1 object
Set UF = New UserForm1
UF.SetObjects N, E
UF.Show
End Sub

Is there a possibility to run a macro in an excel-file (data-source) when data connection is refreshed by another excel-file (data-target)?

a lot of users in our network use an excel-workbook (.xlsm [office 2010]) created from a template.
Now, there are some important changes I've to do in the template and I want all the users to update their workbook but i'd like to avoid to contact all of them.
So, my Idea is to make an auto-update (copying the contents of their workbooks into new created workbooks and delete the former version).
Unfortunately there are no update-macros in the existing workbooks but they reference to a macro in another workbook.
Each time they open their workbooks the data connections become refreshed automatically.
Can I use this refreshing event to trigger a macro in the (data-source) excel-file (maybe by creating a WithEvents-class module)?
You can do something along these lines, where the user opens a workbook, but its job is to control the version. You can change this to have the code modify sheets etc.
The text file, correct, contains ver9, the workbook contains ver8 in the ver_cont worksheet.
Function get_version() As String
Open "c:\workspace\test_ver.txt" For Input As #1
Input #1, get_version
Close #1
End Function
Function check_version()
If get_version = Worksheets("Ver_cont").Range("a1") Then
' Open the workbook here
Else
' Copy the workbook
' Then open it
End If
End Function
You can try this. It uses withevents and runs when the data is updated.
First, you need to create a class name "clsQueryTable" and put this code in it
Option Explicit
Public WithEvents QTQueryTable As Excel.QueryTable
Private Sub QTQueryTable_BeforeRefresh(blnCancel As Boolean)
'Set blnCancel to true to stop the refresh
Debug.Print blnCancel
End Sub
Private Sub QTQueryTable_AfterRefresh(ByVal blnSuccess As Boolean)
'blnSuccess can be used to check for refresh success.
' I would put your update code here!
Debug.Print blnSuccess
End Sub
Then, you can put this code in your workbook_open event on ThisWorkbook
Option Explicit
Dim colQueryTables As Collection
Private Sub Workbook_Open()
Dim shtMySheet As Worksheet
Dim clsQT As clsQueryTable
Dim qtMyQuery As QueryTable
Dim loMyList As ListObject
Dim conn As WorkbookConnection
Set colQueryTables = New Collection
For Each shtMySheet In ThisWorkbook.Worksheets
For Each loMyList In shtMySheet.ListObjects
Set clsQT = New clsQueryTable
Set clsQT.QTQueryTable = loMyList.QueryTable
colQueryTables.Add clsQT
Next loMyList
Next shtMySheet
For Each conn In Connections
conn.Refresh
Next
End Sub

Excel VBA: Sub routine or function to handle hyperlink clicks

There's quite a bit of info about this to be found, but I haven't been able to get it to work for myself.
What I need to do is to have a global sub routine that catches hyperlink clicks for the whole document, not just the active sheet. Why? Because my workbook will have several links in several sheets, which are all "identical" except for their location (and contents of adjoining cells etc.).
This is easy to do with buttons - just connect all of them to the same macro - but I'm having problems doing the same with links.
This works, for one specific sheet:
In the Microsoft Excel Objects -> The worksheet in question:
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
MsgBox "Link i Arket! " & Target.Range.Address
End Sub
When I click the link on the sheet in question, the VBA sub routine for the sheet catches the click and handles it.
The below code, I thought, "should" work for the whole document. That is, catch hyperlink clicks from any sheet in the worksbook. It does not (that is, nothing happens):
Sub Workbook_SheetFollowHyperlink(ByVal Sh As Object, ByVal Target As Hyperlink)
MsgBox "All sheets!"
End Sub
The links, in Excel, when hovering shows:
file://path/to/workbook.xlsm - click once to follow blablabla
What am I missing here?
You can reuse the same code for all worksheets by creating a class with a WithEvents worksheet object and storing the classes in a public collection.
Module1
Public objCollection As Collection
'Call on Workbook_Open
Sub CreateClasses()
Dim ws As Worksheet
Dim HyperlinksClass As cHyperlinks
'Create A New Instance Of The Collection
Set objCollection = New Collection
'Loop All Worksheets
For Each ws In Worksheets
'Create A New Class For This Worksheet
Set HyperlinksClass = New cHyperlinks
'Add The Worksheet To The Class
Set HyperlinksClass.obj = ws
'Add The Class To The Collection
objCollection.Add HyperlinksClass
Next ws
End Sub
Create a class called cHyperlinks
Private WithEvents pWS As Worksheet
Private Sub pWS_FollowHyperlink(ByVal Target As Hyperlink)
'Code to handle hyperlinks here
End Sub
Property Set obj(ByVal objWS As Worksheet)
Set pWS = objWS
End Property

exiting/restarting a word macro that controls excel

I'm running a word macro that
initializes Excel
creates a temporary workbook in excel
when exiting the word userform, terminates excel
However, it seems there is some residual Excel instances/workbook that is not fully closed because when I start the word macro again, I get error: 462, remote server machine ...
initialize userform in a word document:
private sub commandbutton1_click()
dim exc as excel.application
set exc as new excel.application
dim wb as excel.workbook
set wb = exc.workbook.saveas filename:="wordexc" 'creates temp workbook
userform1.show
end sub
run excel processing via a userform1 commandbutton:
private sub commandbutton2_click()
excel.workbook("wordexc").close 'closes temp workbook
dim wb as excel.workbook
set wb = excel.workbook.saveas filename:="wordexc" 'this wb is for actual use
'i do not delete this wb after running cuz it has stored data that will be used
'if user cliks commandbutton2 again, it will be deleted and new wbook with new data
'is created
'processing code
end sub
private sub queryclose (etc...)
'Close Excel
Dim sKillExcel As String
sKillExcel = "TASKKILL /F /IM Excel.exe"
Shell sKillExcel, vbHide
end sub
btw i think the problem is the last part:
Dim sKillExcel As String
sKillExcel = "TASKKILL /F /IM Excel.exe"
Shell sKillExcel, vbHide
Cuz if I stop the macro and terminate EXCEL in task manager, it doesn't give me this problem if I run the macro again...
i
I also tried other methods, like calling a excel workbook i saved in a directory instead of a temporary one via createobject("excel.application") in one sub, exc.quit, but I have to use that termination code above cuz otherwise EXCEL still shows in task manager.
Besides not declaring your objects correctly, you are not (if I may say so) flushing the toilet correctly.
See this example (UNTESTED)
I am using Latebinding instead of Early Binding so that this code is compatible with any version of Excel
'~~> Define your Excel objects so that they are available
'~~> in other userform sub procedures as well.
Dim oXLApp As Object, oXLwb As Object
Private Sub CommandButton1_Click()
Set oXLApp = CreateObject("Excel.Application")
'~~> Show Excel
oXLApp.Visible = True
'~~> Add a new workbook
Set oXLwb = oXLApp.Workbooks.Add
'
'~~> Do some stuff
'
'~~> Save the file
oXLwb.SaveAs "C:\wordexc.xlsx", FileFormat:=51
oXLwb.Close SaveChanges:=False
End Sub
'~~> Close and Quit Excel (Flush Toilet)
Private Sub CommandButton2_Click()
oXLApp.Quit
Set oXLwb = Nothing
Set oXLApp = Nothing
End Sub
Why not do something like this? Basically, you define your excel object globally, and then you can call it's "Quit" method later.
Private objExcel As Excel.Application
Private Sub CommandButton1_Click()
Set objExcel = New Excel.Application
objExcel.Visible = True
End Sub
Private Sub CommandButton2_Click()
objExcel.Quit
End Sub

Resources