Is there a way to stop myDataSet.HasChanges() returning true if the only change is a new row? - vb.net

I have a Button on my Form that when clicked calls myBindingSource.AddNew(). Controls relevant to setting the values on that new row then become visible.
On the close event of that Form i call myDataSet.HasChanges() and if it returns True, i prompt the User if they would like to save the changes they have made.
In the situation where the User clicks to add a new row but then closes the Form, (for whatever reason) without setting any values, myDataSet.HasChanges() will return True obviously because there is the adding of a new row.
What i would like is a way to make it return False if the only change is a new row.
I have tried calling myBindingSource.EndEdit() then myDataSet.AcceptChanges immediately after myBindingSource.AddNew() but myDataSet.HasChanges() still returns True.
I thought by calling myDataSet.AcceptChanges() it would essentially wipe the slate clean and only changes made after that point would be picked up.
Or alternatively if there is a better approach to this i would like to hear it.
I am keen on the idea of only saving back to the DataBase in one go when prompting to save, rather than inserting the new row on the Button.Click and updating that row on each value change.

To be more specified than my comment:
If myDataSet.HasChanges(DataRowState.Deleted Or DataRowState.Modified) Then

Related

Why does MsAccess Record entry only Update (and show in table) after form close and reopen?

Some Background:
I have a database that acts as a ledger (keeps tabs on current payments).
1:Payments for each customer are stored in one table (PaymentTbl),
2:I have another table (TermAgreementTbl) that holds information on the agreed terms of the service
3: My last table (PdUpToTbl) takes the payment information as well as term agreements information from the two other tables and calculates/displays the information in a clearer manner. One of the ways it will do this, is by deleting the last record in PdUpToTbl, and replacing it, or by just adding a new record (case dependent).
Now MY Issue:
I have a form for my TermAgreementTbl that has a subform showing the relevant PdUpToTbl.
A button opens a pop-up form to enter a new payment and update the related PdUpTotbl.
Everything in the back end is functional, however after I enter a new payment (and save and close the pop-up payment form), NO new record is shown in my PdUpToTbl Subform. Instead it shows something like (some irrelevant info redacted):
For the new record to display properly, I have to close the entire form, and reopen it. There has got to be a way to get around this through vba with some code, right?
Thank you for taking the time.
Edit 1:
By the way, after I perform A LOT of vba code, I use this to enter my record:
With pdUpToRS
.AddNew
![DatePaid] = NewRecordSet.Fields("DatePaid").Value
![Amount] = Amount
![AppliedAmount] = AppliedAmount
![OnAcct] = OnAcct
![AllPdUpTo] = AllPdUpTo
![RemainBalDue] = RemainBalDue
![PdUpToString] = PdUpToString
![PaymentType] = NewRecordSet.Fields("PaymentType").Value
![PaymentNumber] = PaymentNumber
![ID] = NewRecordSet.Fields("ID").Value
![PmntTblID] = PmntTblID
![BdCk] = BdCk
![Late] = Lte
![ApplyDiscount] = ApplyDiscount
![ForgetUnderage] = ForgetUnder
![ForgetOverage] = ForgetOver
![Note] = Note
.Update
End With
Update using requery
I have tried to Requery using:
Forms![MainForm]![Subform].Requery
But it gives me the error:
2118 - - - You must save the current field before you run the Requery action.
And if I add the save line:
DoCmd.RunCommand acCmdSaveRecord
Forms![MainForm]![Subform].Requery
I get the resulting error:
2046 - - - The command or action 'SaveRecord' isn't available now.
Ok, the docmd "menu" options to save a record?
They OFTEN run on the form that has the current focus - so often, then the form you want to save is not the one you expected.
I suggest you replace this:
DoCmd.RunCommand acCmdSaveRecord
with
if me.Dirty then me.Dirty = false
Now, above above "me" is is the current form WHERE that code is running, not some form that might happen to have the focus.
Now, as for a form "requery" (to refresh without close then re-open)?
Again, assuming the above just did the save of the data, then to force a re-load of the current form (again, the form in which the code is running), then:
me.Requery
In fact, if you did not have multiple sub-forms, then a me.refresh would probably work (and a me.Refresh will also save the current record).
So, while the if me.dirty = true then me.dirty = false is about the best way to save the current reocrd in the current form where the code is running?
It is a question of where your code is running, and often when the code is running.
In place of the me.dirty = false, you can also do this, but it often will cause a lot more flicker and refreshing then you want.
But, the shortest code to ensure a save of the forms data, and then requery (same as form close then open), would thus be this:
Me.Refresh
me.Requery
However, often issues can arise if you have some dialog form open - so perhaps a closer look at how your code is updating is often imporant.
But, a me.Requery will re-load everything, but you of course want to ensure you force record saves of the data first.
I think the Requery function will serve you well.
https://learn.microsoft.com/en-us/office/vba/api/access.subform.requery

Prevent vee-validate set dirty with data from API response

My problem is that I need to prevent users from leave a page when the form is dirty and ask then if they want to save changes before leave. But, using vee-validate, the form is dirty when its filled with data from API response and I need to set the form dirty just when user change a value on form. I tried sets programmatically but the dirty remains true.
I also tried to use touched, but it seems not work with vue-multiselect
Maybe dirty its not exactly what I need, but the same problem happens using changed for example
This is how I tried to programmatically change the dirty state:
Object.keys(this.$refs.form.fields).forEach(
(key) => (this.$refs.form.fields[key].dirty = false)
)
I also tried change only the form flag
this.$refs.form.flags.dirty = false
but without success
You can use resetForm
This will automatically set the dirty flag to false.
If you want to manipulate the form after you have set the values, you must use resetField

Cannot disable UltraGrid cells

I have an UltraGrid in my project. Data can be entered into each cell, which is then saved to the database. I want to be able to disable all of the cells in the current row EXCEPT for one called Product_Code. Once data has been entered into the active row column (this is entered via a ValueList), I then want all of the other cells to become available for entering data into.
So far I have tried
If Me.ugProducts.ActiveRow.Cells("Product_Code").Value.ToString = "" Then
Me.ugProducts.ActiveRow.Cells("Product_Volume").Activation = Activation.Disabled
Else
Me.ugProducts.ActiveRow.Cells("Product_Volume").Activation = Activation.AllowEdit
End If
But to no success. When the project is built, all of the cells are immediately available to type into, despite no value having been entered.
Why is it not working? What is the best way to do this?
I saw a previous comment on here that has since been deleted, for some reason... However, one solve you can try is:
In the form load; add in ugProducts.DisplayLayout.Override.CellClickAction = CellClickAction.CellSelect - This will mean all of the cells are disabled, but you'll still be able to select the ValueList for Product_Code
Now, in the CellListSelect event of ugProducts, use the following code ugProducts.DisplayLayout.Override.CellClickAction = CellClickAction.Edit (After any validation checks or anything that you have in the method already, it will go in here somewhere, just keep trying things if you aren't too sure where)
Anyway, this should now let you fill them in as you wish.

Button doesn't work after DataGridView Validating Event

I have a Form with a TabControl on it. On one of the TabPages is a DataGridView with a New- and Delete-Button below it. I also have a Validating-Event for the DataGridView. Inside the Event I do some checking. If the conditions are not met I do a simple:
e.Cancel = True
Return
But after that my Delete-Button isn't working anymore. Even if I set a Breakpoint right at the start of the Click-Event nothing is happening what could that be? I have set the CausesValidation to false on the Button.
Update
I need to handle both Events, because the Sum of this DataGridView is compared to another value. The Sum can't be smaller or bigger than the other Value. But the User can enter what he wants as long as at the End the Sum is correct. I can't do that in the CellValidating because as soon as I change a Value the Sum doesn't match anymore
Update
I have observerd the following Scenarios where it doesn't work:
I change Data in the DataGridView and then trigger the Validating-Event. It starts working again when I input correct Data and switch Tabs
I create a new Row, trigger the CellValidating-Event and after that the DGV Validating-Event

DataGridView detect changes not working as expected

I have a program that is going to load data into a DataGridView, where users can edit/add/delete data. When they close out of the form, if there are any changes made, it will ask if the user wants to save the changes to the database.
So I have a DataTable that I load and assign to the DataSource of the DataGridView. I can then make changes to the data within the table, and if I call the DataSet.Update method, it updates.
However, if I call the DataTable.GetChanges method and look to see the changes, I get nothing, unless I have tabbed/clicked/whatever off of the current row of the DataGridView (in which case .GetChanges works) This leads me to believe that the changes are not committing to the DataTable unless the row loses focus.
So, is there a way to check to see if any cell is changed in a DataGridView, or a way to commit those changes without tabbing off of the row?
Again, this fails me if I don't change the row in the GridView, but works otherwise. I want it to work in both situations.
Dim changedRows As New DataTable()
changedRows = dtInfo.GetChanges(DataRowState.Modified Or DataRowState.Added Or DataRowState.Deleted)
If Not changedRows Is Nothing Then
....
End If
You can call the Form.ValidateChildren method, this will validate and commit all controls in the form, including your DataGridView. This method returns false if there is a validation error.