I've got a treeview control in my form. I would like to be able to edit the node in the tree and push the change to Access DB. However, I'm having trouble finding an appropriate event. MSDN treeview events reference page advices AfterLabelEdit, but I am not able to get it to work. Is anyone aware of any workaround/solution?
Snippet of the code I use (I've added onClick and onDblClick for comparison, as they work):
Private Sub xMyTreeview_Click() 'OK
testit
End Sub
Private Sub xMyTreeview_DblClick() 'OK
EditLabel
End Sub
Private Sub xMyTreeview_AfterLabelEdit() 'Problem
AfterLabel
End Sub
Sub EditLabel()
Me.xMyTreeview.StartLabelEdit
End Sub
Sub AfterLabel()
MsgBox prompt, vbOKOnly, "afterlabel"
End Sub
Sub testit()
Dim nodSelected As MSComctlLib.Node ' a variable for the currently selected node
Set nodSelected = Me.xMyTreeview.SelectedItem ' get the currently selected node
NodesStrLength = Len(nodSelected.Key)
Dim NodeStr As String
Dim StrToChange As String
StrToChange = nodSelected.Key
NodeStr = Mid(StrToChange, 2, NodesStrLength - 1)
Me.txtNodeID = NodeStr
Me.sfrmDOCNODE.Visible = True
End Sub
Your link is to the .net Windows Form Treeview but MSComctlLib is the older Visual Basic Common Controls: http://msdn.microsoft.com/en-us/library/aa443023(v=vs.60).aspx
Note the event prototype is different; if you don't declare it with the correct arguments it will never get raised;
Private Sub object_AfterLabelEdit(cancel As Integer, newstring As String)
Related
I am trying create a button which changes the value of AllowEdits to False and another for true for a subform. I am using the below code. I get a Runtime error 424 each time I run it.
Option Compare Database
Private Sub Toggle_Edit_Click()
Dim strForm As String
strFormName = Me.Name
Call ToggleEdit(Me)
End Sub
and
Option Compare Database
Public strFormName As String
Sub ToggleEdit(myForm As Form)
Call Message
ctrlControl.AllowEdits = True
End Sub
and if you were interested
Sub Message()
MsgBox "Remember not to overwrite incorrect records"
End Sub
Please add Option Explicit at top of your modules!
I think AllowEdits is a Form property, not a Control property.
Option Explicit
Sub ToggleEdit(myForm As Form)
myForm.AllowEdits = Not myForm.AllowEdits
End Sub
If the code is behind the form itself, you can use Me.
Sub ToggleEdit() 'no parameter
Me.AllowEdits = Not Me.AllowEdits
End Sub
If you want to act at control level, use Locked or Enabled properties.
I have an Access form with a listbox and a combo box.
Private Sub Form_Open(Cancel As Integer)
'... misc code
me.comboBox.RowSource = "sql statement"
call comboBox_AfterUpdate
End Sub
Private Sub comboBox_AfterUpdate()
listbox.Selected(0) = true
End Sub
Private Sub listbox_AFterUpdate()
'.... important code that updates the form
End Sub
On the form load/open, the the code runs as
Form_Open > comboBox_AfterUpdate > listbox_AfterUpdate
However after the form has already loaded, when the combo box is changed and the comboBox_AfterUpdate is triggered, the listbox_AfterUpdate() is NOT triggered.
I would move the code in the listbox_AfterUpdate() to a separate sub-routine, but that would call the code to run twice when the form loads. Any ideas on why this happens?
Similar issue here:
http://www.tek-tips.com/viewthread.cfm?qid=1395160
You could use two custom functions and use optional parameters to know the context in which it is called. That way you have full control over when which function does which.
E.g.
Public Sub MyFunc1 (Optional CalledFromLoad As Boolean)
Public Sub MyFunc2 (Optional CalledFromLoad As Boolean)
Private Sub comboBox_AfterUpdate()
Call MyFunc1 False
End Sub
Private Sub listbox_AFterUpdate()
Call MyFunc2 False
End Sub
Private Sub Form_Open(Cancel As Integer)
Call MyFunc1 True
End Sub
Moving all your code gives you a greater degree of customization, and can help you avoid calling the same code twice.
You could possibly set a global variable in MyFunc1, then trigger MyFunc2 by changing the listbox, and then reset that global variable again. Numerous solutions are possible.
This is a continuation from a previous post of mine: How to select a printer for entire job?, where I basically want to print a series of reports from a form in my Access database.
Which refers to this help doc: https://msdn.microsoft.com/en-us/library/ee336132(v=office.12).aspx
I'm trying to create the combobox with active printers in it in order to temporarily change the default printer for a series of documents. I'm tripped up on where it says "pass a reference to a ComboBox control"... How does one implement this?
Here's the code I have so far, where cboPrinterSelect is the combobox name:
Private Sub cboPrinterSelect_Load(Cancel As Integer)
Call GetPrinterList
' I'm not sure about this next part either'
cboPrinterSelect.Value = GetPrinterList.value
End Sub
'***************************************************
Private Sub cboPrinterSelect_AfterUpdate(Cancel As Integer)
Set Application.Printer = Application.Printers(cboPrinterSelect.ListIndex)
End Sub
'***************************************************
Private Sub GetPrinterList(ctl As Control)
Dim prt As Printer
For Each prt In Printers
ctl.AddItem prt.DeviceName
Next prt
ctl = Application.Printer.DeviceName
End Sub
Any help/advice would be appreciated.
EDIT:
Here is my updated code, which is still throwing an error (described in Andre's comments):
Private Sub Form_Load()
Call GetPrinterList(Me.cboPrinterSelect)
End Sub
'*********************************************************
Private Sub cboPrinterSelect_AfterUpdate(Cancel As Integer)
Set Application.Printer = Application.Printers(cboPrinterSelect.ListIndex)
End Sub
'***************************************************************
Private Sub GetPrinterList(ctl As Control)
Dim prt As Printer
For Each prt In Printers
ctl.AddItem prt.DeviceName
Next prt
ctl = Application.Printer.DeviceName
End Sub
The first part, the call of GetPrinterList(), must go into the On Load event of the form.
Private Sub Form_Load()
Call GetPrinterList(Me.cboPrinterSelect)
End Sub
That should be all that's missing.
The default printer is pre-selected by this line:
ctl = Application.Printer.DeviceName
And make sure that cboPrinterSelect has a RowSourceType of Value List.
Try the following code, it will display all connected Printers in the combo_box in your User_Form.
Public Sub GetPrinters()
' Use a large array (supports up to 100 printers).
ReDim result(100) As String
Dim wshNetwork, allPrinters As Object
' Get the network object
Set wshNetwork = CreateObject("WScript.Network")
Set allPrinters = wshNetwork.EnumPrinterConnections
' Printers collection has two elements for each printer.
For i = 0 To allPrinters.Count - 1 Step 2
Print_Series.cboPrinterSelect.AddItem allPrinters.Item(i + 1)
Next
' call your user form and combo box will have all active printers
Print_Series.Show
End Sub
I have a form with numerous images, each of which performs a series of actions when clicked. I can create a Private Sub with all of the actions for each button, however I think this is inefficient. Rather, I'd like to record all the actions in one Macro and then call this Macro when each image is clicked. To do so, I'd need the single Macro to refer to the current image selected and not refer to any image by name. Is this possible?
My current code includes the following:
Me.Image001.BorderColor = RGB(1, 1, 1)
Me.Image001.BorderWidth = 2
Me.Image001.BorderStyle = 1
I'd need to amend this so that it amends the border colour/width/style etc of whichever image is selected, and not a specific named image ('Image001').
Thanks!
You should use event sinking.
With event sinking you could bind to an event your own procedures.
You can see an example here http://p2p.wrox.com/access-vba/37472-event-triggered-when-any-control-changed.html
In simple words you create a module where you bind the event to your specific implementation . Then on the form you are interested you create a collection where you register the controls you want to "follow" the event sinking...
My sub sinking for checkboxes (i have alot)
1st a class module name SpecialEventHandler
Option Compare Database
Private WithEvents chkbx As CheckBox
Private m_Form As Form
Private Const mstrEventProcedure = "[Event Procedure]"
Public Function init(chkbox As CheckBox, frm As Form)
Set chkbx = chkbox
Set m_Form = frm
'Debug.Print frm.Name
chkbx.AfterUpdate = mstrEventProcedure
End Function
Private Sub chkbx_AfterUpdate()
'your Code here
End Sub
Private Sub Class_Terminate()
Set chkbx = Nothing
Set m_Form = Nothing
End Sub
Then on the form you want to use event sinking
Option Compare Database
Dim spEventHandler As SpecialEventHandler
Private colcheckBoxes As New Collection
Private Sub Form_Open(Cancel As Integer)
Dim ctl As Control
For Each ctl In Me.Detail.Controls
Select Case ctl.ControlType
Case acCheckBox
Set spEventHandler = New SpecialEventHandler
spEventHandler.init Controls(ctl.NAME), Me
colcheckBoxes.Add spEventHandler
End Select
Next ctl
End Sub
You could always create a Standard Sub, then call it on the click of the button. Something like
Public Sub changeColor(frm As Form, ctrl As Control)
frm.Controls(ctrl.Name).BorderColor = RGB(1, 1, 1)
frm.Controls(ctrl.Name).BorderWidth = 2
frm.Controls(ctrl.Name).BorderStyle = 1
End Sub
So when you click an image all you have to do is,
Private Sub Image001_Click()
changeColor Me, Image001
End Sub
I'm having an issue with report events that I haven't
encountered before in Access prior to Access 2007.
I'm using using Access 2007 for a Front-end to a SQL Back-end.
I have a Class, ReportEvents, that I use for the reports.
In a report's Report_Open event I instantiate and then use this class to
handle events like activate, Close, NoData and I also put common code
such as exporting data to excel instead of a report.
This code was working fine in a previous Access 2003 application (mdb) I was using,
but it isn't working as expected in 2007 (accdb). In my tests the call to a non event public sub, ProvideXLOption works like a charm, but none of the events are being fired
from the ReportEvents class. I didn't change the code I just imported it into the
project. I set up break points but they aren't being hit. I changed all of them to
public events and then called them within the test reports event and they worked fine.
I set up another report in Access 2007 with the same results. I've checked
the startup settings in Access and they are fine. I even removed and re-added
the database location from the trusted locations without any luck.
Has Microsoft modified the Events Code or is this just a simple code error on my part that I'm not seeing? It's gotta be something simple. My brain is just toast (my son decided to stay awake after last night's feeding).
Class ReportEvents Code:
Option Compare Database
Option Explicit
Private WithEvents rpt As Access.Report
Const strEventKey As String = "[Event Procedure]"
Public Property Set Report(Rept As Access.Report)
Set rpt = Rept
With rpt
.OnActivate = strEventKey
.OnClose = strEventKey
If LenB(.OnNoData) = 0 Then
.OnNoData = strEventKey
End If
End With
End Property
Public Sub Terminate()
On Error Resume Next
Set rpt = Nothing
End Sub
Private Sub rpt_Activate()
LoadPrintRibbon
End Sub
Private Sub rpt_Close()
Me.Terminate
End Sub
Private Sub rpt_NoData(Cancel As Integer)
Dim strMsg As String
strMsg = "No Records were found that match your criteria."
MsgBox strMsg, vbInformation, rpt.Name & _
": No Match. Report Cancelled"
Cancel = True
End Sub
Private Sub LoadPrintRibbon()
#If AccessVersion >= 12 Then
If rpt.RibbonName <> "PrintPreview" Then
rpt.RibbonName = "PrintPreview"
End If
#End If
End Sub
';;Provides user with option to send data to Excel instead of a report
Public Sub ProvideXLOption(Cancel As Integer)
'... some XLOption Code
End Sub
In the Test Report Code:
Private Sub Report_Open(Cancel As Integer)
Dim rptEvts As ReportEvents
Set rptEvts = New ReportEvents
Set rptEvts.Report = Me
';;Let User User Choose to Export Data to Excel or Display the report
rptEvts.ProvideXLOption Cancel
End Sub
I figured it out. It was a scope issue The ReportEvents class variable rptEvts, was inside the Report_Open sub. Because of this it wouldn't exist when the other events happened. It should be at the module level and not within the procedure.
Dim rptEvts As ReportEvents
Private Sub Report_Open(Cancel As Integer)
Set rptEvts = New ReportEvents
Set rptEvts.Report = Me
';;Let User User Choose to Export Data to Excel or Display the report
rptEvts.ProvideXLOption Cancel End Sub
End Sub
It's amazing what a little rest will do for you.