MS-Access hidding and showing a button conditionally through vba - vba

I am developing a quality control system for my company, and I i want to connect it to a label printer, which is already taken care off, the problem now is with the button itself.
I want the print label button to only be enabled and visible after the whole check was made, what i've got now is this:
Private Sub Form_BeforeUpdate(Cancel As Integer)
Button_label.Visible = False
Button_label.Enabled = False
End Sub
Private Sub Motor_OK_Change()
Dim ok As Boolean
ok = Motor_OK.Value
If ok = 1 Then
Button_label.Visible = True
Button_label.Enabled = True
End If
End Sub
It does work on conceiling the button, but it fails when trying to enable it again and making it visible upon making the check. It's important to refer that I have tried using If ok = True instead of If ok= 1, I dont know how important that is.
Thanks

You are not testing for both conditions (ok=0), perhaps the following will work:
Replace:
If ok = 1 Then
Button_label.Visible = True
Button_label.Enabled = True
End If
With:
Button_label.Visible = ok
Button_label.Enabled = ok
New Solution:
Instead of using the Form Before_Update event, use Form_Current event. If there is only 1 record, you can also use the Form_Load event. I would also suggest that you remove the Visible property and use only the Enabled one so users can see their is print functionality.
Private Sub Form_Current()
'button_Label.Visible = False
button_Label.Enabled = False
End Sub
Instead of using the Motor_OK Before_Updateevent, use After_Update event
Private Sub Motor_OK_AfterUpdate()
Dim ok As Boolean ' defaults to False
If IsNumeric(Motor_OK.Value) Then ok = True ' remove this statement if Motor_OM is
' alpha numeric.
If Not IsNull(Motor_OK.Value) Then ok = True ' otherwise following statement
' to avoid NULL error
'button_Label.Visible = ok
button_Label.Enabled = ok
End Sub
Let me know if I can be of further help.

Related

Datagridview Start editing on load

I want my user to be able to begin typing when a form loads that has a datagridview loaded in the first row, first column. No matter what I do, the user has to click into the cell to begin typing.
This is what I have tried so far in the form on load event.
With dgTable
.Focus()
.Rows.Add(50)
.EditMode = DataGridViewEditMode.EditOnEnter
.CurrentCell = .Rows(0).Cells(0)
.BeginEdit(False)
End With
Can anyone tell me what I need to do?
dgTable.Item(0, 0).Selected = True
Will select the first cell and allow typing on load.
And remove .BeginEdit(false) and .CurrentCell = .Rows(0).Cells(0)
So:
With dgTable
.Focus()
.Rows.Add(50)
.EditMode = DataGridViewEditMode.EditOnEnter
.Item(0, 0).Selected = True
End With
The load event isn't ideal, since the control isn't visible yet. Try using the EditProgrammatically setting and use the form's Shown override method instead:
Protected Overrides Sub OnShown(e As EventArgs)
MyBase.OnShown(e)
dgTable.EditMode = DataGridViewEditMode.EditProgrammatically
dgTable.BeginEdit(False)
End Sub

How to mark a radio button as checked with no action performed?

I have a form with CheckBox and RadioButton controls. When people click on the buttons/boxes it saves the results to my DB. Later, I might want someone else to retrieve the form and make changes or continue using it.
When I pull the info back from the database into a new "search" form (that looks exactly like the form used to submit the data), I want the radio buttons to reflect the state they were in when the form was saved. So if a box was TRUE (checked) when saved, I want it to show TRUE (checked) on the new form.
HOWEVER, when I use
radiobutton.checked = True
It DOES mark my button as checked.... it ALSO acts like the button was clicked again. So I have duplicate results in my database. It will keep doing this every time the form is opened.
So, I want a way to mark the box as checked (the state it was in when saved) but NOT CAUSE THE EVENT AGAIN.
Here's an example:
str = "SELECT * from OpenEvents WHERE EventID = " & eventId & ""
Dim cmd6 As OleDbCommand = New OleDbCommand(str, myConnection)
dr = cmd6.ExecuteReader()
While dr.Read()
contactType = dr("ContactType").ToString
abend = dr("Abend").ToString
paged = dr("Paged").ToString
shortSummary = dr("ShortSummary").ToString
eventNotes = dr("EventNotes").ToString
impacting = dr("Impacting").ToString
L1Engaged = dr("L1Engaged").ToString
L2Engaged = dr("L2Engaged").ToString
managerEngaged = dr("ManagerEngaged")
IncTicket = dr("IncTicket").ToString
End While
myConnection.Close()
If contactType = "Call" Then
CallRadioButton.Checked = True
ElseIf contactType = "IM" Then
IMRadioButton.Checked = True
ElseIf contactType = "Other" Then
OtherRadioButton.Checked = True
ElseIf contactType = "Alert" Then
AlertRadioButton.Checked = True
Else
End If
If abend = "True" Then AbendCheckBox.Checked = True
If paged = "True" Then PagedYes.Checked = True
ShortSummaryTextBox.Text = shortSummary
DetailsTextBox.Text = eventNotes
If impacting = "True" Then ImpactingYesRadioButton.Checked = True
If L1Engaged = "True" Then L1YesRadioButton.Checked = True
If L2Engaged = "True" Then L2YesRadioButton.Checked = True
If managerEngaged = "True" Then ManagerYesRadioButton.Checked = True
IncTicketTextBox.Text = IncTicket
Just to turn it into an answer:
Create a boolean to be used at the form load event. Start it's value as true by default and when the load finishes, set it's value to false.
At every radio/check event you check the value, if it's true just exit the sub, otherwise do whatever it's supposed to do.
Best regards.
You could use Click event instead of CheckedChanged event.
Doing so, if you want to raise the event linked to the RadioButton you can use PerformClick instead of Checked = True.
If you want to change checked status without raising the event you can use Checked = True.
Here a little example:
Private Sub RadioButton1_Click(sender As Object, e As EventArgs) Handles RadioButton1.Click, RadioButton2.Click, RadioButton3.Click
Select Case sender.name
Case Is = "RadioButton1"
Me.Label1.BackgroundColor = Color.Yellow
Me.Label2.BackgroundColor = Color.Gray
Me.Label3.BackgroundColor = Color.Gray
Case Is = "RadioButton2"
Me.Label1.BackgroundColor = Color.Gray
Me.Label2.BackgroundColor = Color.Yellow
Me.Label3.BackgroundColor = Color.Gray
Case Is = "RadioButton3"
Me.Label1.BackgroundColor = Color.Gray
Me.Label2.BackgroundColor = Color.Gray
Me.Label3.BackgroundColor = Color.Yellow
End Select
End Sub
Private Sub Btn_ChangeSelected_Click(sender As Object, e As EventArgs) Handles Btn_ChangeSelected.Click
Me.RadioButton1.Checked = True
End Sub
Private Sub Btn_PerformClick_Click(sender As Object, e As EventArgs) Handles Btn_PerformClick.Click
Me.RadioButton1.PerformClick()
End Sub
If you click Btn_ChangeSelected RadioButton1 will be checked but no event will be raised.
If you click Btn_PerformClick RadioButton1 will be checked and RadioButton1.click event will be raised.
I would save the state of the radiobuttons at form closing event to my.settings and read all back on the form load event. This way you keep the last settings of your radiobuttons before exiting the program.
In my case, I ended up moving my code from
_CheckedChanged
event, that was the default when clicking on the control from design view, to a
_MouseClick
event. Solved all my problems. Seems it was a bit silly that was the default, but lessons learned. And all working as I need now.
Thanks for all the input!!!

Task is running and cannot be finished

Have strange behaviour in my task which is not finishing. I use this all the time but i suppose its because sub i am passing to it is iteracting with form - changing selection and refreshing some listbox probably therefore its stack there but i am not sure. Lets see the code:
This is the sub i want to be run in task:
Public Sub UnselectExistingConnectionsItems()
Dim SentenceId, SubSubKategorieId, SubSectionId As Integer
SubSectionId = CbSubSections.SelectedValue 'combobox
If WithSubSubkategorie = SubSubKategorieEnum.Without Then
SubSubKategorieId = 0
Else
SubSubKategorieId = CbSubSubKategorie.SelectedValue 'combobox
End If
Unselect:
For i As Integer = 0 To LB_Sentences.SelectedItems.Count - 1
Dim sKey As ListBoxItem
sKey = LB_Sentences.SelectedItems(i)
SentenceId = HtmlDescription.HtmlSentence.GetSentenceIdByName(sKey.Text)
If HtmlDescription.HtmlSubSubSections_Sentences.CheckIfConnectionAlreadyExist(SentenceId, SubSectionId, SubSubKategorieId) Then
sKey.IsSelected = False
LB_Sentences.Refresh()
GoTo Unselect
End If
Next
End Sub
i put it to Task like this:
Dim pic As New FrmCircularProgress(eCircularProgressType.Line)
Dim work As Task = Task.Factory.StartNew(Sub()
'--Run lenghty task UnselectExistingConnectionsItems()
'--Close form once done (on GUI thread)
pic.Invoke(New Action(Sub() pic.StopCircular()))
pic.Invoke(New Action(Sub() pic.Close()))
End Sub)
'--Show the form
pic.ShowDialog()
Task.WaitAll(work)
and FrmCircularProgress is just form ( i use it almost everywhere where i have to user wait and its working besides this particural case):
Public Class FrmCircularProgress
Sub New(progressType As DevComponents.DotNetBar.eCircularProgressType)
InitializeComponent()
CircularProgress1.ProgressBarType = progressType
StartCircular()
End Sub
Public Sub StartCircular()
Me.CircularProgress1.IsRunning = True
End Sub
Public Sub StopCircular()
Me.CircularProgress1.IsRunning = False
End Sub
End Class
what could be wrong? is it because procedure is interacting with listbox and combobxes? If so how to fix that, i read something about invoking listbox and comboboxes but have no idea how to fix that.
EDIT:
I think besides those lines:
sKey.IsSelected = False
LB_Sentences.Refresh()
I have to make those:
LB_Sentences.Invoke(Sub() sKey.IsSelected = False
End Sub)
LB_Sentences.Invoke(Sub() LB_Sentences.Refresh()
End Sub)
because i am in diffrent thread. Somehow i dont know how to convert those lines:
SubSectionId = CbSubSections.SelectedValue
SubSubKategorieId = CbSubSubKategorie.SelectedValue
probably loop also have to be invoked. Waiting your help.
There is a rule that says "The only thread that can modify a control in a window is the thread that created the window". Any other thread trying to modify something in the window will generate a cross-thread call exception.
So in your first edit you got it right, you have to invoke the functions.
However, this doesn't fix your problem of not finishing Task.
I believe that doing sKey.IsSelected = False does not unselect anything in your ListBox, therefore causing an infinite loop... Also that Goto statement is very bad programming habits and should not be used. There is always another solution that will make your code easier to debug/maintain/read...
ListBoxItem is not a type that exists in the .Net Framework. So either you created that class either it's something else (and I don't know what...)
What you can do to solve your problem is :
Get the indices of all selected items in a list
Run through your list, and check if they should be selected :
If they should be selected, do nothing
if they shouldn't, unselect them.
Which makes your code like this (and you remove that ugly Label and Goto that you don't want in your code)...
Public Sub UnselectExistingConnectionsItems()
Dim SentenceId, SubSubKategorieId, SubSectionId As Integer
SubSectionId = CbSubSections.SelectedValue 'combobox
If WithSubSubkategorie = SubSubKategorieEnum.Without Then
SubSubKategorieId = 0
Else
SubSubKategorieId = CbSubSubKategorie.SelectedValue 'combobox
End If
'We create an array to remind our initial selection
Dim sel = New Integer(LB_Sentences.SelectedItems.Count - 1) {}
LB_Sentences.SelectedIndices.CopyTo(sel, 0)
For i = 0 To sel.Length - 1
Dim sKey As ListBoxItem
'We get our selected item
sKey = LB_Sentences(sel(i))
SentenceId = HtmlDescription.HtmlSentence.GetSentenceIdByName(sKey.Text)
If HtmlDescription.HtmlSubSubSections_Sentences.CheckIfConnectionAlreadyExist(SentenceId, SubSectionId, SubSubKategorieId) Then
'We must remove it from the selection
LB_Sentences.Invoke(Sub() LB_Sentences.SelectedItems.Remove(sKey))
End If
Next
'We do the Refresh at the end so we gain some process time...
LB_Sentences.Invoke(Sub() LB_Sentences.Refresh())
End Sub

Why is my event handler firing two times?

I have a bunch of panels that I am adding to a single parent panel and I want to add event listeners to all of the panels but not until after they have all been added to the parent (becuase I don't want the event listeners firing each time a new panel gets added). So I am using the following code:
Dim temp_object As question_bar = Nothing
For Each q As Object In review_holder.Controls
If TypeOf q Is question_bar Then
temp_object = q
AddHandler temp_object.Resize, AddressOf temp_object.resize_me
End If
Next
For Each q As Object In review_holder.Controls
If TypeOf q Is question_bar Then
temp_object = q
temp_object.resize_me()
End If
Next
But I noticed that the resize_me() subroutine is getting fired twice for each control. I only want it to fire once. So I traced it out using this code
MsgBox((New System.Diagnostics.StackTrace).GetFrame(1).GetMethod.Name)
and I see that each time it gets called the calling methods are both this subroutine and _Lambda$_365. What the heck is that? How do I find out where that is coming from?
BTW, this is a winforms app using VS2012.
EDIT ------------------------------------------------------------------------
Public Sub resize_me()
MsgBox((New System.Diagnostics.StackTrace).GetFrame(1).GetMethod.Name)
If Me.minimized = True Then
Me.Height = 0
Exit Sub
End If
number_panel.Width = my_parent.number_width
number_text.Width = my_parent.number_width
number_separator.Left = number_panel.Right
question_panel.Left = number_separator.Right
question_panel.Width = question_panel.Parent.Width * initial_question_width + (question_padding * 2)
End Sub
Well changing size properties when you are inside a resize event could explain why your code is recalled again a second time. Usually I try to avoid this kind of situations but this is not always possible. In these cases then a global variable that acts as a flag to block the reentry could save the day
Dim insideResize As Boolean
Public Sub resize_me()
if insideResize = True Then
Exit Sub
End if
insideResize = True
Try
If Me.minimized = True Then
Me.Height = 0
Exit Sub
End If
number_panel.Width = my_parent.number_width
number_text.Width = my_parent.number_width
number_separator.Left = number_panel.Right
question_panel.Left = number_separator.Right
question_panel.Width = question_panel.Parent.Width * initial_question_width + (question_padding * 2)
Finally
insideResize = False
End Try
End Sub
To stay on the safe side with this patterns remember to always use a Try/Finally block to be sure that when you exit from the Resize event the global flag is correctly set back to false.

How to use a checkbox to change values in an SQL database in asp.net

I currently have system which has a web front end and a back office system. User can book properties online or call our office to book a property. In the admin system on the web front, I have two check boxes to determine if the property is available on the front end or the back office system. This is controlled using a Check box. The code for the check box is as follows;
<asp:CheckBox ID="CheckBoxAvailableToWeb" runat="server" TextAlign="Left" Text="Available for web bookings"
Checked="true" />
I have an field in an SQL Database called "isAvailableToWeb" which has a Boolean result. What I want to achieve is if the check box is checked, the value of the "isAvailableToWeb" field is set to "True" or set to "False" if un-checked.
I have tried to complete this function using the following code;
Protected Sub CheckBoxAvailableToWeb_CheckedChanged(sender As Object, e As EventArgs, ByVal beachhutid As Long)
Using dbContext = New bbhasDBEntities
Dim item
item = (From i In dbContext.tblBeachHuts Where i.beachHutId = beachhutid Select i).First()
If CheckBoxAvailableToWeb.Checked = True Then
item.AvailableToWeb = True
Else
item.AvailableToWeb = False
End If
dbContext.tblBeachHuts.Attach(item)
Call dbContext.SaveChanges()
End Using
End Sub
This code doesn't throw up any errors but doesn't also make the change that I would like to see.
I have a button on this page that saves the information so I would also like to know if it would be better, once the code is working, to put it in that Sub.
You need to call dbContext.SaveChanges to persist to the database (assuming bbhasDBEntities is an instance of DbContext), assign to the entity rather than the boolean and call First() to get the first matching element rather than a collection.
Protected Sub CheckBoxAvailableToWeb_CheckedChanged(sender As Object, e As EventArgs, ByVal beachhutid As Long)
Using dbContext = New bbhasDBEntities
Dim item
item = (From i In dbContext.tblBeachHuts Where i.beachHutId = beachhutid Select i).First()
If CheckBoxAvailableToWeb.Checked = True Then
item.AvailableToWeb = True
Else
item.AvailableToWeb = False
End If
Call dbContext.SaveChanges()
End Using
End Sub
Try using 1 and 0 instead of true and false when assigning values into AvailableToWeb.
I use this method with a dataset and it works correctly.