Unable to push bound control changes to the dataset - vb.net

I am trying to compare the original and current value for a data bound text box. I've done a bit of research and tried a few methods but I can't seem to get it to work. I'm using vb.net via Visual Studio 2012. Database is running on a SQL 2012 server and I'm using a stored procedure to provide the data.
Fill statement:
Me.SpGetEmployeeTableAdapter.Fill(Me.DsEmployee.spGetEmployee, cboEmpId.SelectedValue)
My textbox is called txtLastName and txtLastname.Text is bound to spGetEmployeeBindingSource.LastName
I have a method that handles txtLastName.LostFocus so I can watch the values as follows:
Private Sub LastName_Out() Handles txtLastName.LostFocus
Dim x as String
x = "Hi" (breakpoint)
End Sub
I run the app and load the data for employee Smith using the fill above. I go to the text box, change it to Jones and tab out. I hit the break point above and check the values in a Watch window:
me.DsEmployee.spGetEmployee(0)("LastName", DataRowVersion.Original).ToString
me.DsEmployee.spGetEmployee(0)("LastName", DataRowVersion.Current).ToString
Both lines show Smith as the value but on the screen you see Jones.
My research indicated that I may have to run EndCurrentEdit to push the textbox.text value down to the dataset but I've had no luck. The following are three examples of how I tried to end the current edit but so far the values stay the same and the dataset doesn't pick up the changes:
BindingContext(Me.DsEmployee.Tables.Item("Me.DsEmployee.spGetEmployee(0)")).EndCurrentEdit()
BindingContext(Me.DsEmployee.spGetEmployee.Rows(0)).EndCurrentEdit()
BindingContext(Me.DsEmployee).EndCurrentEdit
I have no doubt at all that I'm doing it wrong but I sure would appreciate a leg up.
Thank you!

I ran a couple of tests and actually got this working. Here is what I needed to do before testing the "Current" data row version:
me.SpGetEmployeeBindingSource.EndEdit()
Once I ran that line of code I could test for the value in DataRowVersion.Current and I could see the new value. Additionally when I check me.dsEmployee.HasChanges it returns True when it returned False without the EndEdit.

Related

How to handle Access "Run-Time Error 3021 - No current record" after DoCmd.Requery?

I have been having a quite annoying issue on my access project.
It is an Access 2007 - 2016 file.
My database has two queries that I intend to use to filter data to feed combo-boxes.
On one of my forms I have done that with success. The first list is fed from a table, and the succeeding ones are fed by filtering their respective table based on the previous list selection.
Here is a screenshot of my form that worked out.
And here is part of the code that goes with it:
Private Sub frm01ListSetor_Click()
DoCmd.Requery (qry01_frm01ListArea)
Me![frm01ListArea] = Null
DoCmd.Requery (qry02_frm01ListEquip)
Me![frm01ListEquip] = Null
Me![frm01TextID] = Null
End Sub
Private Sub frm01ListArea_Click()
DoCmd.Requery (qry02_frm01ListEquip)
Me![frm01ListEquip] = Null
Me![frm01TextID] = Null
End Sub
Here are the queries that goes along with the code above:
qry01_frm01ListArea
SELECT tblAreas.ID_Area, tblAreas.NomeArea
FROM tblAreas
WHERE (((tblAreas.SetorArea)=[Forms]![frm01_AddEquip]![frm01ListSetor]));
qry02_frm01ListEquip
SELECT tblEquipamentos.ID_Equipamento, tblEquipamentos.NomeEquipamento
FROM tblEquipamentos
WHERE (((tblEquipamentos.SetorEquipamento)=[Forms]![frm01_AddEquip]![frm01ListSetor]) AND ((tblEquipamentos.AreaEquipamento)=[Forms]![frm01_AddEquip]![frm01ListArea]))
ORDER BY tblEquipamentos.ID_Equipamento;
The code above works just fine. It filters data to previous selection accordingly and it also clears the data and selection of the "righter" lists every time another value is selected on the "lefter" ones.
So that was a form I created to help me out on populating my equipment database.
Let us get to the problematic twin now:
I created another form for Maintenance Orders of these equipment.
This one must be more user friendly since other people will use it. Therefore I used Combo-boxes for value selection instead of List Boxes. I say this before hand because it is the only thing I could notice that differs the new form from the one above.
Here I have this:
Screenshot of troubled form
After the expanded Combo-box on image 2 is selected I should run the following code:
Private Sub frm02SetorOM_Click()
DoCmd.Requery (qry04_frm02CBArea)
Me![frm02AreaOM] = Null
DoCmd.Requery (qry05_frm02CBEquip)
Me![frm02EquipamentoOM] = Null
End Sub
Private Sub frm02AreaOM_Change()
DoCmd.Requery (qry05_frm02CBEquip)
Me![frm02EquipamentoOM] = Null
End Sub
It is basically the very same thing I have done on the first form but with different variables.
But I get a "Run-time error 3021: No current record" every time I select a value on my "Setor" field.
The crash happens at the "DoCmd.Requery (qry04_frm02CBArea)" line.
Here is the query for this form's Area field (qry04_frm02CBArea):
SELECT tblAreas.ID_Area, tblAreas.NomeArea
FROM tblAreas
WHERE (((tblAreas.SetorArea)=[Forms]![frm02_SubmitOM]![frm02SetorOM]));
But the thing that is confusing me the most is that when I click "End" on the Run-time error dialog box, my Area combo-box - that was empty before - even with the error gets the proper options like if it actually "requeried".
How can I fix this issue?
Thank you in advance.
Btw, this is my first Access project so please consider that on the response.

MS Access Database form not updating after SQL requery

I have a report that runs from a query. The query does use a global variable but this is not the problem but needed for the explanation. The function for the variable is:
Function Var1() As String
Var1 = strVar1
End Function
The query where statement is:
WHERE (((IIf([MinOfDueDayMin]<0,0,Int([MinOfDueDayMin]/7)+1))<Var1()+1) AND ((tblEquipment.Retired)=False))
which uses the var1 function
The criteria is on a field that is actually a calculation and that is where I think the problem starts.
The report is run for a command on another form using the following code:
strVar1 = InputBox("Enter Number of Weeks for report")
If strVar1 = "" Then Exit Sub
DoCmd.OpenReport "rptEquipPmSchedule", acViewReport
Everything works just fine
On the report I have a double click event that opens a form. This form uses part of the same query. (not the same one but two levels higher) thiS allow the user to change things so i expect to use requery for the report.
If i double click and then not even change anything and then go back to the report I have #ERROR in the fields that have the calculations
i put a me.requery in the activate event of the report. this did not work.
So I tried a work around.
When I double click the report field, i close the report and send the strVar1 value to the form that is opened. then when I close the form I reasign the strVar1 just in case it is lost be an assignment by another user (currently I am the only one using this but did it just to be sure it had the correct value.) Then I open the report again but still get the errors. I did not expect this at all. thought starting the report from scratch would certainly work. I even closed the form just after assigning strVar1.
then in final effort. When I close the form I run the exact same code:
strVar1 = InputBox("Enter Number of Weeks for report")
If strVar1 = "" Then Exit Sub
DoCmd.OpenReport "rptEquipPmSchedule", acViewReport
Which will force the user to input the value for strVal1. Even though this is not what I want but tried this for troubleshooting and I still get #ERROR.
When I run the report for a form that does not have any of the same field, no issues. When I run the report or keep it open with a requery from the form that has the same data, the report will not give the correct results. Note that if I run the query itself, the data in the query is correct.
i also tried using a number instead of Val1() in the query and got the same results.
i also tried the refresh button in the ribbon and get Unknown Function Name and all the data in the report is lost.
Anyone got any ideas??
While your textual explanation is difficult to understand the entire scope, consider re-assessing your workflow. The entire objective is to allow users to run customized criteria for reporting. And your main issue is the strVal does not persist in memory so all references to it fails.
Consider the following points:
Have users set criteria on a dedicated unbound form with button click for report where that report instance is immutable for viewing/printing only and if needed to be changed must be re-run (i.e., button re-clicked).
Access has no need for VBA's InputBox() as strVal can be an unbound textbox on this unbound form whose value remains intact for all open windows.
Have function and all its references point to form field: Form!myFormName!strValuetextbox
Because reports on pretty much any software/web app system is not used as a GUI interface to run actions, users will know if they intend to change report criteria, close current report or go back to entry point and change strVal then re-click button to re-run report.
Keep data entry/input (primary use of forms) separate from data export/output (like reports). From developer and user standpoint this compartmentalization will save you headaches down the road.

VB.Net ComboBox (as Dropdown) not translating text to DisplayMember with Databinding

I inherited a fairly large project at work that is undocumented and written in VB (originally started pre .NET, ended around .NET 2). I'm in the process of updating / refreshing a lot of the code, but have run into an annoying issue that I haven't found the solution for yet. This system utilizes a UI, a Web Service, and a SQL DB.
Problem: I have a Databound Combobox (originally set to DropDownList - I'm changing it to DropDown, which is what started this mess - going back isn't an option) that is tied to a DataSet that comes from a Web Service. When a user types in the item they want manually, the data from the text field doesn't seem to associate itself with the DisplayMember, which forces the WS/SQL query to fail (it is sent a blank value when it's expecting a ValueMember). If the user types in a partial selection and then chooses the value they want from the DisplayMember list using the arrow keys or tab, the query goes off without a problem.
My Question: How do I get the text field to translate to the DisplayMember which will then properly tie itself to the ValueMember which will then allow the query to execute correctly? Sorry for making this sound complicated or convoluted; I'm sure the answer is easy and I'm just glazing over it.
The relevant bit of code is:
With cmbDID
If dtsLU.Tables.Contains(reqTable) = True Then
.DataSource = dtsLU.Tables(reqTable)
.DisplayMember = "zip"
.ValueMember = "gridID"
End If
End With
cmbDID.DataBindings.Clear()
cmbDID.DataBindings.Add("SelectedValue", dtsData, strDT & ".gridID")
I've tried changing "SelectedValue" to "Text", which almost works - but it directly translates to gridID and skips zip which ends up with an incorrect Web Service response since the zip and gridID field values are not synced (zip (DisplayMember) may be 5123 while gridID (ValueMember) may be 6047). I've tried changing "SelectedValue" to "SelectedIndex", and that got me no where.
Any help is greatly appreciated.
EDIT
To add some clarification to the process, the below pseudo code / description is roughly what happens. I could post the whole module, but I feel that would just muddy the whole question even more.
Private Sub A
FormAlpha is created with 1 ComboBox in the form of a DropDown
This DropDown is populated with a DataSet
DataBinding with a blank DataSet is added to the control to keep track of the users input
End Sub
lblSubmit_Click event is triggered on FormAlpha by the user after they have populated the DropDown with their data. lblSubmit_Click calls Private Sub Submit
Private Sub Submit
BindingContext(DropDown DataSet, tableName).EndCurrentEdit() is called
DataSet.HasChanges() is processed
If changes are present, changes are processed
HERE lies the problem
If the user has manually typed in the DropDown field, but not hit an arrow key or tab, then the DataSet registers a change, but returns a null value in all fields - it knows something was entered, but that data apparently didn't pass through the DataSet for the ComboBox (ListItems or SelectedIndex didn't change / fire I'm guessing). If the user selects the item with the arrow keys, the DataSet has the proper input (I'm assuming the Data was validated by the control at this point).
If the processed data is good, a value is entered into the database
If the processed data is bad (empty), an error is returned
End Sub
If the above can't be solved with what I've provided, but someone still knows a better way to handle this type of situation, I'm all ears. Rewriting the module isn't ideal, but fixing this problem is a necessity.
Alright, while this fix may not be ideal, it is a fix none the less.
The bare bones problem was that the text value of the DropDown wasn't causing the data to actually affect the SelectedIndex / SelectedValue of the control unless you interacted with it using the arrow keys or a mouse click. So, while the DropDown would read "1234", in reality the control saw "".
The fix I have in place for this is simply calling comboBox.text = comboBox.text whenever the user hits the submit button.

Pass parameter value to Revit family using .net api

I want to pass the parameter values to Revit family.I have spend many hours on google. In result i got few links which tells Read and Write Parameter Values with VB.NET
Read and Write Parameter Values with VB.NET
in this example we are fetching parameters and writing a value in text file called ParametersValue.txt. But i am confused, how should i pass this file to Revit?
I'm hoping someone can steer me in the right direction. I would really appreciate it!
One of the first things I would do after downloading the SDK mentioned in the previous post, is install the included revit lookup addin. This has been incredibly valuable in figuring what elements are called in the API, as well as determining which storage type the parameter is using. If all of the parameters you want to update are strings, those will be fairly straightforward to set from your text file. However, if,for example, the parameter value that you think is a string is actually set by an elementid, then there will be some coding involved to get the proper info to set the parameter value.
You can easily pass parameters to component families using "FamilyManager" class. The FamilyManager class provides access to family types and parameters. Just get the parameter and set its value. As we are working in family editor for component families, we have to load the parameter values in the project. I have tried this on Revit 2019. You have to
Open family in family editor
Activate the plugin
Click on Load into Project button on addins ribbon.
Then check the parameter value in the properties of that family.
Public Sub SetParamtersForComponentFamilies(ByVal doc As Document, ByVal parameterValue As String)
Dim f As Family = doc.OwnerFamily
Using trans As Transaction = New Transaction(doc, "Creating transaction for parameters")
trans.Start()
Dim familyMgr As FamilyManager = doc.FamilyManager
Dim n As Integer = familyMgr.Parameters.Size
Dim comment As FamilyParameter = familyMgr.get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_COMMENTS)
familyMgr.Set(comment, parameterValue)
TaskDialog.Show("Paramters", "TypeComments : Updated")
trans.Commit()
End Using
End Sub
I use C# when writing Revit API code because that's what all the samples are written in, but I might be able to get you pointed in the right direction with some additional details. Are you looking to assign a value to a specific parameter? For example: Height=30"?
If so you first have to "get" the parameter. In the example in spidernet he goes through every parameter of a selected element:
Dim element As Autodesk.Revit.DB.Element = SelElement(cmdData.Application.ActiveUIDocument.Selection).Element 'Prompts you to select an element
For Each p As Parameter In element.Parameters 'Goes through every parameter in "element" and assigns the parameter to "p"
If p.Definition.Name = "Height" Then 'Check if "p" is the name you want, "Height"
p.Set(2.5) 'Because Revit knows FEET, so in order to type in 30in you use 2.5
End If
Next 'Loop through parameters
If you're looking for it to do something else, please post again.
Also, not sure you're aware, but a blog that is FULL is great Revit API info is Jeremy Tammik's: http://thebuildingcoder.typepad.com. A lot of his examples are C#, which is why I started learning C# instead of VB.NET.
If you don't have it already, make sure you get the SDK for Revit 2014 here: http://images.autodesk.com/adsk/files/Revit2014SDK_RTM0.exe
It has a TON of samples that might help too. Good Luck!

Problem with datagridview and AddNew

I've created a VB 2008 program to track work requests. It all works perfectly on a VISTA box, but I am having an issue with the program on an XP environment with adding new records.
Basically I've got 2 tabs: TAB 1 holds a datagridview with limited info and a calendar. Selecting dates on the calendar change the info in the datagridview. TAB 2 holds all the available info for that record in text/combo boxes. Both the datagridview and text boxes use the same Binding Source, so they are always in sync whenever the user selects a row from the datagridview. When you select the NEW button, TAB 2 appears with all the text boxes empty so the user can add data. If you look back on TAB 1, you see an empty, new row added to the datagridview (user can not directly add a row in the datagridview as AllowUserToAdd is set to false). If you let the app stay in the AddNew record state on VISTA, you remain on that new record until you select SAVE or CANCEL. On XP, however, after 1 minute time lapse, all the empty fields will eventually fill in with an existing record for that particular calendar day. When you look back on TAB 1, you no longer see the new empty row, you only see existing records previously saved.
Any ideas on how to resolve?? Thanks for any assistance.
Here is the code for adding new records:
Private Sub cmdNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdNew.Click
'Focus on Work tab
TabControl1.SelectedTab = tabWork
'Change the files from read-only
bEditMode = True
ChangeEditMode()
'Clear the current information stored in the fields
Try
Me.BindingContext(WorkRequestBindingSource).AddNew()
Catch ex As Exception
System.Windows.Forms.MessageBox.Show(ex.Message)
End Try
'Hidden text boxes populate with current selected calendar
'Used to populate TimeIn and DateNeed because if never clicked on, will populate as NULL on save
dtpDateNeed.Text = txtDate.Text
dtpTimeIn.Text = txtTime.Text
End Sub
This is definitely an environmental issue. To solve the problem I would need to know which browsers you are using on each machine and some of the settings on each.
It sounds like the XP machine is refreshing the page after a timeout period and therefore munging the new record. I have seen that happen before and it stinks.
You might need to consider saving some more state information in the viewstate to catch that kind of thing.
If the code is exactly the same I wonder if it is an environment issue e.g. something like different international options or version of framework?