Dataset is empty while it is not empty at first - vb.net

I have the following piece of code
_Foo = String.Concat(_Foo, " Var = '", _varValue, "' ")
_Bar = DsInvoice.viewInvoice.Select(_Foo, _Order)
If _Bar.Count > 0 Then
When I place the debug lines, the Dataset is actually returning rows, and _Bar has a count of 116. Yet when it is at the 3rd line (the if statement) _Bar is empty and the count returns 0. Without any reason I just lost my data.
Let me know if you need more information (I'm actually a PHP programmer and I had to fix a legacy bit of code :(. I lack VB experience to give more background information on this code.

_Bar has no rows because there is no value equal to the _varValue in the "Column" (a.k.a "Property") in the datatable.
*Even if the Property is numeric I doubt wrapping it with single quotes will matter. *
Tip: F8 (VB.Net) or F11 (C#) to step the code control (Yellow Line) onto the second line of code. Then hover your mouse over the viewInvoice word on the second line shown in your question, you'll see the ObjectBrowser Tooltip appear and in it will be a Magnifying Glass with a dropdown. Click it (the dropdown) and select the DataTable View to help you debug this problem.
You can change the Select(...) criteria in run/debug time and then (by dragging the yellow arrow in the line number margin up a line) see the effect of the different Select criteria to work out what is going wrong.

Related

MS ACCESS: VBA too fast leading to field updating only if Toggle Breakpoint in code, need timer?

I am currently doing a Purchase Order "software" under Access and I am having issue with calculating the amount after a item quantity (qty) update.
When I have Toggle breakpoints in my VBA code on the "after update" event, after updating qty = 5 and going through the lines of code, I have the parent text field correctly updated from the subform one (which is the sum of the 'Total Price' fields).
The code contains a Refresh in order to add the right value rather than the old one:
.
.
However, when I remove the toggle breakpoint, I think that the VBA code does not have enough time fully process the refresh command, which update the parent text field with the wrong (old) value.
This issue leads to have a discrepancy between the actual subform calculated total, and the value added to the parent table (here I removed the toggle breakpoint, and added 1 on the second line item, but the calculation gave a 250 rather than a 251):
When I look at the values in the code, when the breakpoint is on the updating line, you can see that the value of the field is the right one, but the 'watch' field shows the old value:
.
.
Do you guys have a solution to make sure all the fields are updated before going to the next line?
I was thinking using some sort of delay, or an "application wait until processing done" type of command but I cannot find anything that is actually working;
Let me know,
Cheers!
EDIT 1:
The "Expected Total Cost" is bound to a table field called "curPOExpectedTotalCost", which is why I use VBA code to populate the data into its dedicated textbox (called "txtcurPOExpectedTotalCost").
The main goal is simply to have this bound field being correctly updated; I want to be able to change the qty or the unit price and automatically populate the right total PO price into "Expected Total Cost" which is bound to a table; the issue is that it works well when I am running each lines one by one using the breakpoints in my code, but does not work when I remove them; this tells me it is probably too fast, hence a way of delaying the next command or a command to wait for processing to be done.
EDIT 2:
I found a workaround, but it seems overpowered for this simple task I was trying to achieve; good side is that it removes the middle man (the subform textbox that sum all the total prices):
I open a recordset and iterate a variable until I can populate the result into the dedicated "Expected Total Cost" bound textbox:
DoCmd.RunCommand (acCmdRefresh)
Dim RS As DAO.Recordset
Dim SQL As String
SQL = "SELECT numPONumberAndRevID, numPOContentQtyOrdered, numPOContentPrice FROM tblPOSCONTENT WHERE numPONumberAndRevID = " & Nz(Me.Parent.MasterPOID.Value)
Set RS = CurrentDb.OpenRecordset(SQL)
Do While Not RS.EOF
ExpectedCalculatedCost = ExpectedCalculatedCost + RS("numPOContentQtyOrdered") * RS("numPOContentPrice")
RS.MoveNext
Loop
RS.Close
Set RS = Nothing
Me.Parent.txtcurPOExpectedTotalCost.Value = ExpectedCalculatedCost
We could arrange in a simple way.
We name the detail input subform control as sfrmDetail, the main total control can be assigned with a .ControlSource like:
Me.txtcurPOExpectedTotalCost.ControlSource="=[sfrmDetail].[Form].[txtSubFormExpectedTotalCost]"
When txtnumPOContentQtyOrdered updates, your main form changes instanteneously without any VBA code.
In the subform, say sfrmDetail, that will be embedded in the main form as subformcontrol sfrmDetail (yes with the same name), we assign a .ControlSouce=Sum(Qty*UnitPrice) for the control txtSubFormExpectedTotalCost, at the footer of the subform.
Solution II:
As #June7 pointed out in comments, the Total cost, that can be calculated dynamically, should be better only for display only (form input display, report printing, but not saved in disk).
OK, now we want at any cost to stock in field tblMain.curPOExpectedTotalCost the total cost with a slight data redundancy, so in the main form we have Me.txtcurPOExpectedTotalCost.ControlSource="curPOExpectedTotalCost"
In the subform sfrmDetail, we can update with:
Option Compare Database
Option Explicit
Private Sub txtnumPOContentQtyOrdered_AfterUpdate()
Me.Recalc
Me.Parent.txtcurPOExpectedTotalCost.Value = Me.txtSubformExpectedTotalCost.Value
End Sub
Me.Recalc() updates all calculated fields of sfrmDetail before we change the target main table field.
Please consult also Is storing counts of database record redundant? for data redundancy.

Getting Selected Items from a Listbox

Good Wednesday All.
I am running into a brick wall (easy for a shade tree coder to do) I have a Listbox that i populated with a datatable. I want to get the all LicenseID's from the selected items. In other words, if the user selects 3 out of 8 of the list box, I need to get the LicenseID for each of those 3.
Below is how I populated the listbox
Using cmd As New OleDbCommand(cmdText, conn)
conn.Open()
Dim reader As OleDbDataReader = cmd.ExecuteReader()
dt.Load(reader)
ListBox1License.DataSource = dt
ListBox1License.DisplayMember = "InstitutionTypeAbrev"
ListBox1License.ValueMember = "LicenseID"
End Using
I need to get the selected items from the listbox to use later.
I am thinking of adding the selected Items to an array.
I have searched around STackOverflow for some examples but none seem to work for me.
Any Help Appreciated
I'll show you how to derive the answer for this yourself:
I've set up a form:
Really simple; the listbox is like your listbox. The button is just there to give me an easy way to stop the code and examine what is going on.
I wrote some code to populate some things into my listbox. It's a screenshot because it doesn't matter that you have exactly this code, so you don't need to write this code (hence why I'm making it hard to copy paste):
I've double clicked my button to make a click handler. I haven't written any code, but I have put a breakpoint on the method declaration - see it's red? Click the margin where the dot is, to put breakpoints in your code. When you hit them, the code stops and waits for you to inspect:
I've run my app and clicked my button. The code has stopped and VS has switched to showing me the code, not the app:
I can now point to some variable that is in scope (like ListBox1) and see a tooltip, or I can open the Locals/Autos windows and see variables that are in scope and drill into them:
Expand you ListBox in the Autos/Locals window. It has a lot of properties. Scroll to SelectedItems:
SelectedItems is a collection of things.. We can tell partly because Microsoft is good at naming collections of things with a plural name, and because the inspector says "enumerate the enumerable" .. it means that it is a bunch of things that we can ForEach to look through
Expanding it we see that my selecteditems has only one thing selected (i truly did only have one selected item in my list when I clicked the button)
We can see that an entry in the SelectedItems collection is a DataRowView type of object. We can see that a DataRowView has a Row property that is a DataRow.. This Row is the DataRow in the DataTable to which the list is bound (you set the DataSource to a DataTable; this is a row from that table).
Every time you dig into the tree another level, that's like using either a dot or an indexer in your code. At this level we've gone listbox1.SelectedItems(0).Row..
So from this we can see that we need a code like:
' we will "enumerate the enumerable"
For Each drv as DataRowView in listbox1.SelectedItems
Dim originalRow = drv.Row 'we could do this to get the row...
Dim selectedAnimaId = row("AnimalID") ' ..and then index the row to get the animal ID ..
Dim selectedAnimalId = drv("AnimalID") ' ... or it's actually possible to index a DataRowView directly, so you can skip the row part
Next drv
It can be handy to write code while you're stopped on a breakpoint so you can look at the values of things as you're writing, and check you're going in the right direction. You might need to use F10 (or whatever key is associated with "step over"/"step into") to move the yellow bar along and execute code lines one by one:
You can only move the code execution along if you've written complete, legal code, but it doesn't have to be logically correct. You can back up and execute again by dragging the yellow arrow in the margin (or right clicking and choosing Set Next Statement). Here I've put some dummy statement in to move along to, so i can check that my animalID is correctly set in X like I expect . I point to X to see the value:
The standard ListBox won't help you with that, past getting the DataRowView objects from the SelectedItems collection. As an alternative, here's a custom control that you can use in place of a standard ListBox that will help you:
Public Class ListBoxEx
Inherits ListBox
Public Function GetItemValue(item As Object) As Object
Dim index = Me.Items.IndexOf(item)
If (index <> -1 AndAlso Me.DataManager IsNot Nothing) Then
Return Me.FilterItemOnProperty(Me.DataManager.List(index), Me.ValueMember)
End If
Return Nothing
End Function
End Class
You can then call GetItemValue and pass any item and get the same value back as you would if that was the SelectedItem and you got the SelectedValue. To get all the values in an array:
Dim licenseIDs = myListBoxEx.SelectedItems.
Cast(Of Object)().
Select(Function(o) CInt(myListBoxEx.GetItemValue(o)).
ToArray()
For more information, see here.
In case you're unaware, if you add a class to your project and it is a control or component, once you build, it will appear automatically at the top of the Toolbox window.
If you already have a standard ListBox in place and you don't want to have to delete it and add a new control, you can edit the designer code file by hand to change the existing control. To do that, open the Solution Explorer and select a node within your project, click the Show All Files button, expand the node for your form, double-click the designer code file and then replace ListBox with ListBoxEx (or whatever you call it) in the relevant places. I'd advise creating a backup copy or syncing with source control first, in case you mess it up.

VBA MSHFLEXGRID wrong .ROW information in the CLICK event

I'm using the VBA MSHFLEXGRID, 2 grids in fact in the same Form, one below the other so when I choose a row in the first grid, the second one shows info regarding the first grid row selection.
Well, the problem is that the second grid, after choosing a row in the first grid which brings to no information in the second one (I put the data through the own grid recordset, and if i dont want it to show information, i do an exit in the load procedure, it gets crazy and the .ROW property in the Click event starts returning a fixed number, like for example 4, instead of the actual row being clicked. Always a number that represents a higher row than the last one (one that is even out of the grid). I tried also the .MOUSEROW and this one returns 0 all the time (when the grid becomes crazy).
This never happens with the first grid, only with the second one. There's nothing I can do without real information about the row being clicked. I've seen that with different resolutions the problem gets reset. Seems not to happen with low resolutions like 1360x768, but it does with 1920x1080 and 2560x1440.
SOLVED! I was trying cases and more cases to try to understand why it happens sometimes in random cases and finally found it. The problem appears when you set the recordset directly to the grid (Set Grid.Recordset = xxxx) and this xxx is empty. It is, EOF. So I was doing a .Clearstructure, and then the SET. After this, if i did another SET (another selection of the second grid) with a non empty recordset, then it would go crazy.
So what I did was simple assigning first a recordset object to check if the SQL query is empty or not, and if it's not empty and only then, assign the recordset to the grid. Oh my god, this was bringing me crazy after a long time.

QTP - Clicking on a button with a given value

I've started using QTP last weekend so I'm still a bit confused about some things.
I've coded a function that opens an URL on IE, performs some actions and writes a report. But I have a little problem: at a certain point the function has to click on a button to go on but this button's value is changed at every refresh of the page.
For example: at the first access the button's value (or label) is "Results List (51)" but, if I refresh the page, the value becomes "Results List (11)".
What changes is the number inside the brackets (that identifies the number of results inside the list).
Obviously I recorded the action only one time and the result is this:
Browser("myBrowser").Page("myPage").Frame("myFrame").WebButton("Results List 51)").Click
How can I click on the button without having to worry about it's value?
You should open the object repository and have a look at the description that was create for your WebButton then make the property in question a regular expression.
In your case the value should be Results List \(\d+\), this means Result List followed by open-parentheses, followd by one or more digits (a number) followed by close-parentheses.
Here's an explanation on how to use regular expressions in UFT.
This question reminded me of the days when I was a beginner in QTP ;) I think I still am!
Coming to your question -
If you don't really care about what is inside the brackets then you can just give Results List*.* but if you want to check if there is a bracket and digits within it then use the value suggested by Motti i.e. Results List (\d+)
Detailed Steps as you are a rookie:
1) Go to Resources->Object Repository
OR
In the Resources pane expand your action and double-Click the local object repository (You recorded hence the objects will be in local)
2) Click on the Concerned Object so that the object properties specific to this object is displayed.
3) Select the property (name?), at the extreme right you will see a button to configure the value, click on it.
4) Type the text Results List (\d+) or Results List*.*, select the checkbox for regular expressions.
5) A message box will appear, Click on No and then OK button.
Your script should run now!

Setting Focus on DataGridView Control programmatically in Visual Basic

I want to programmatically set the focus to the last row (bottommost, its only one column wide) in the DataGridView control for Visual Basic. How can I do so?
So far, I have tried
DGV.Rows.GetLastRow(DataGridViewElementStates.Selected)
without success, though I did not expect that to work.
It absolutely must select that last cell. Otherwise, the application is nearly impossible to use!
Here is a screenshot of what I am making with this: http://www.mediafire.com/?mmyogzytgzt
The "Paste Clipboard Contents" button only pastes into the selected cell, though I guess I could find a workaround.
I solved it. I used a workaround to add the text in directly. I don't need this anymore!
To select the last column, last row in c# (sorry I don't have a vb project I'm working right now:
this._dg.ClearSelection(); // eliminates what they already have selected if you need
this._dg[this._dg.ColumnCount-1, this._dg.RowCount-1].Selected = true;
In VB.net replace 'this' with 'me', and [] with ().
This is also useful:
this._dg.Focus();
this._dg.CurrentCell = this._dg[this._dg.ColumnCount - 1, this._dg.RowCount - 1];
this._dg.BeginEdit(false); // true if you want all text highlighted
// for deletion or replacement