I have multiple comboboxes where users have the option of selecting an item. If no item is selected I insert NULL into SQL-SERVER:
if cboSchool.text="" then
g_strSQL = g_strSQL & "NULL,"
else
g_strSQL = g_strSQL & "'" & cboschool.itemdata(cboschool.listindex) & "',"
End if
My problem is as follow: Later on I allow the user to edit the information that they previously didn't select. So later on when they want to edit the information, I need to be able to have the application realize that there was a value or there wasn't a value in the table in (SQLSERVER), compare if its different from the value that was selected. And if the information is different then need to update the table. This is what my code looks for EDIT:
If g_RS!SchoolID <>cboSchool.ItemData(cboSchool.ListIndex)Then
g_strSQL2 = g_strSQL2 & " School ID = '" & cboSchool.ItemData (cboSchool.ListIndex) & "',"
End If
The problem Im seeing is that g_RS!SCHOOLID shows as "NULL", however it does notice that the value is different from cboschool.itemdata and it just skips to the end of the if statement. I don't understand how it doesn't see the difference.
If Val("" & g_RS!SchoolID) <> cboSchool.ItemData(cboSchool.ListIndex) Then
It's because of the null value that it doesn't see a difference.
You could have:
If g_RS!SchoolID <> "Hello world!" Then
g_strSQL2 = "DROP TABLE X"
Else
MsgBox ("g_RS!SchoolID = Hello world!")
End If
and as long as SchoolID is NULL you'd get a messagebox.
You could fix this with something like:
If Iif(IsNull(g_RS!SchoolID), "", g_RS!SchoolID) <> cboSchool.ItemData(cboSchool.ListIndex) Then
'do stuff
End If
Related
I have an SqlDataReader that is declared like this:
Dim myReader As SqlDataReader
myReader = SqlHelper.ExecuteReader(ConnectionString, "storedProcedure1", CInt(myTextBox.Text))
Later I use the results like this:
If myReader.HasRows Then
While myReader.Read()
Row = Table1.NewRow()
Row.Item("REF") = myReader.GetString(0)
Row.Item("CD") = myReader.GetString(1)
Row.Item("NAME") = myReader.GetString(2)
Row.Item("KEY") = myReader.GetDecimal(3)
Row.Item("STRING") = myReader.GetString(0) & " - " & myReader.GetString(1) & " - " & myReader.GetString(2).ToString().Replace("'", "") & " - " & myReader.GetString(4).ToString().Replace("'", "")
Table1.Rows.Add(Row)
'Fill Drop Down
drpMenu.Items.Add(New ListItem(myReader.GetString(0) & " - " & myReader.GetString(1) & " - " & myReader.GetString(2).ToString().Replace("'", "") & " - " & myReader.GetString(4).ToString().Replace("'", "")))
End While
End If
myTextBox is a textbox that the user enters a possible location number that gets searched for using the stored procedure. If the user enters a valid location number, this works great and I have no problems. If they enter a non-existent location number, I get an exception:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
I would think that the If myReader.HasRows line would keep me from trying to read and manipulate results that don't exist but there must be something I'm missing. myTextBox is already being validated elsewhere in the code to make sure the user typed in an integer without any wacky characters so bad input doesn't seem to be the problem either.
How do I find out whether the location number exists before calling SqlHelper.ExecuteReader()? Or maybe the better question is how do I gracefully handle this exception and tell the user the location wasn't found?
EDIT: Here's the stored procedure.
ALTER PROCEDURE [dbo].[storedProcedure]
-- Add the parameters for the stored procedure here
#MBR as integer
AS
BEGIN
EXEC ('{CALL RM#IMLIB.spGETLOC( ?)}', #MBR) at AS400
END
EDIT #2: When I run the stored procedure in SMS and pass a valid location, it returns what I expect. If I pass an invalid location number, it returns nothing.
First. create a local variable...and cast the textbox value to the local variable...to make sure that isn't the error.
dim myValue as Int32
myValue = '' convert textbox value to an int.
Second...typically, my datareader code looks like this.
If (Not ( reader Is Nothing) ) then
If reader.HasRows Then
Do While reader.Read()
Console.WriteLine(reader.GetInt32(0) _
& vbTab & reader.GetString(1))
Loop
End If
End If
(You'll have to adjust the GetInt32 or GetString and the ordinal number to your specific case of course).
My guess is that your child-procedure (RM#IMLIB.spGETLOC) has logic in it that does NOT return a row if there isn't a match.
You can still return a result....that has no rows in it. ** (Read that again).
For example
Select ColA, ColB from dbo.MyTable where 0=1
This will return a result, with no rows. That is different from not returning a(ny) select statement..(Read that again)
My guess is that this little nuance is where you get an issue.
APPEND:
If you cannot change the child-stored procedure....
Create a #TempTable...
Populate the #TempTable with the child-stored procedure.
Do a select from the #TempTable.
Here is a generic example:
IF OBJECT_ID('tempdb..#TempOrders') IS NOT NULL
begin
drop table #TempOrders
end
CREATE TABLE #TempOrders
(
ColumnA int
, [ColumnB] nchar(5)
)
/* Note, your #temp table must have the exact same columns as returned by the child procedure */
INSERT INTO #TempOrders ( ColumnA, ColumnB )
exec dbo.uspChildProcedure ParameterOne
Select ColumnA, ColumnB from #TempOrders
IF OBJECT_ID('tempdb..#TempOrderDetails') IS NOT NULL
begin
drop table #TempOrderDetails
end
I finally figured out my issue.
Later in my code, I had a DataRow array that was empty if the location couldn't be found. I was getting the exception because it was trying to grab an Item from array(0) which makes complete sense.
I missed it initially because I thought it was a DataRow, not a DataRow array. Man, I hate fixing up code I didn't write...
I made a code capable of downloading values in a web page and it works well. Since the values are taken in real time, that is, data download is performed only when there are actually changes, I need if a certain value is changed.
I then created a code that allows me to get check from all elements of the array with the updated values and the array with the old values.
The code actually detects when a given result has changed, but for some strange reason, the message appears to infinity, as if it were stuck in a foor that takes no arguments, and this is very strange.
For Each abc As Country_Data In lista
For Each xyz As Country_Data In vecchia_lista
If abc.casa = xyz.casa And abc.ospite = xyz.ospite Then
If abc.Result <> xyz.Result Then
MsgBox(abc.casa & " - " & abc.ospite & " -- " & abc.Result)
Exit For
End If
End If
Next
Next
Variable definition
Dim lista As New List(Of Country_Data)
Dim vecchia_lista As New List(Of Country_Data)
Private Structure Country_Data
Dim casa As String
Dim ospite As String
Dim Result As String
End Structure
how to fix this?
Based on your comments, I'm gathering that you only ever want to see one message box, when it finds the first case where a result has changed (even though there could be others after that).
The Exit For you're using only exits from the inner For loop, and thus the outer For loop continues to loop, which is probably what you're observing.
You can do something like this:
Dim keepLooping As Boolean = True
For Each abc As Country_Data In lista
For Each xyz As Country_Data In vecchia_lista
If abc.casa = xyz.casa And abc.ospite = xyz.ospite Then
If abc.Result <> xyz.Result Then
MsgBox(abc.casa & " - " & abc.ospite & " -- " & abc.Result)
keepLooping = False
Exit For
End If
End If
Next
If (Not keepLooping) Then Exit For
Next
That way when you want to stop looping, it will set the boolean flag and that will be observed by the outer loop, causing it to exit as well.
First time writing on a forum but this one really left me no choice and it seems that nobody had the same problem as I have... not a good sign...
I have a project to use the COM Server of a software we use internally and need to use one of their built-in function which requires a recordset as an input and return another recordset with the results (important because I need to stick with the recordset).
Here's breifly what I tried. I create a recordset from scratch and fill it with some hardcoded data just for testing purposes. Once my recordset is filled, I want to look at the data just to be sure everything works well, but I'll have to do the same eventually with my results.
The problem I get is it seems that the GetRows() method return only 1 row every time depending on the last row I moved to. But once it's called, I cannot get the other records. I'm already using the GetRows() method with an actual query and still with an ADODB recordset and it works perfectly. Building a recodset from scratch seems less easy.
I need to put all my data in an object to work with it. But even if I want to use only a recordset, I cannot access to all data in it. Very fustrating... something I'm missing here...
Error I get: either bof or eof is true or the current record has been deleted
Thanks in advance,
Public Function GetFDBData() As Boolean
Dim filtersView As New ADODB.Recordset
Dim rsFields(1) As Object
Dim fieldsAPT(3, 1) As Object
Dim dataView As Object
Dim i As Integer
rsFields(0) = "Field Name"
rsFields(1) = "Filter"
fieldsAPT(0, 0) = "ISIN"
fieldsAPT(0, 1) = "=CA89*"
fieldsAPT(1, 0) = "Currency"
fieldsAPT(1, 1) = "=CAD"
fieldsAPT(2, 0) = "Line"
fieldsAPT(2, 1) = "=Bond"
fieldsAPT(3, 0) = "Redemption Date"
fieldsAPT(3, 1) = "=20230*"
Try
'Build the recordset containing APT fields and filters (in the same variable fieldsAPT)
filtersView.CursorLocation = ADODB.CursorLocationEnum.adUseClient
filtersView.Fields.Append(rsFields(0), ADODB.DataTypeEnum.adVarChar, 30)
filtersView.Fields.Append(rsFields(1), ADODB.DataTypeEnum.adVarChar, 30)
filtersView.Open(, , ADODB.CursorTypeEnum.adOpenStatic, ADODB.LockTypeEnum.adLockOptimistic)
Dim fieldAPT(1)
For i = 0 To UBound(fieldsAPT)
fieldAPT(0) = fieldsAPT(i, 0)
Console.WriteLine(fieldAPT(0)) 'Works fine
fieldAPT(1) = fieldsAPT(i, 1)
Console.WriteLine(fieldAPT(1)) 'Works fine
filtersView.AddNew(rsFields, fieldAPT)
filtersView.Update()
Console.WriteLine(filtersView.RecordCount) 'I can see 1 2 3 4 no problem here
Next i
Dim xx As Integer = filtersView.RecordCount 'xx is 4 as expected
Console.WriteLine("xx: " & xx)
filtersView.MoveFirst() 'Will move to the first record or whatever record
'dataView = filtersView.GetRows() 'I expected this line to work, but same results
For i = 0 To xx - 1
dataView = filtersView.GetRows()
Console.WriteLine(dataView(i, 0).ToString) 'ISIN, normal
Console.WriteLine(filtersView.RecordCount) 'Still equals 4, normal
Console.WriteLine(filtersView.BOF) 'False, normal
Console.WriteLine(filtersView.EOF) 'True, which is NOT normal
Console.WriteLine(filtersView.AbsolutePosition) 'Get -3 not sure why (position 1 related to 4???)
Console.WriteLine(filtersView.MaxRecords) 'Get 0 not sure why
filtersView.MoveNext() '!!!! Here is where it fails !!!! Cannot go more than i=0
Next i
GetFDBData = True
Catch ex As Exception
MsgBox(ex.Message)
GetFDBData = False
Finally
'Clear memory
filtersView.Close()
End Try
End Function
Also, if I do this,
Dim xx As Integer = filtersView.RecordCount 'xx is 4 as expected
Console.WriteLine("xx: " & xx)
filtersView.MoveLast()
Instead of
Dim xx As Integer = filtersView.RecordCount 'xx is 4 as expected
Console.WriteLine("xx: " & xx)
filtersView.MoveFirst()
It will return "Redemption date" in the for loop after. Which makes sense because it is the last record. But puting movefirst even after does'nt solve the issue... still one row only. So the data is there, but I really can't extract one line and one line only...
Try changing your cursor type to adOpenDynamic
EDIT: OK,your line
dataView = filtersView.GetRows()
is causing your cursor to travel to the end of the recordset, try moving it outside your loop and following it with a new MoveFirst like so
filtersView.MoveFirst() 'Will move to the first record or whatever record
'dataView = filtersView.GetRows() 'I expected this line to work, but same results
dataView = filtersView.GetRows()
filtersView.MoveFirst()
Dim sTemp As String = ""
For i = 0 To xx - 1
'Console.WriteLine(dataView(i, 0).ToString) 'ISIN, normal
Console.WriteLine(filtersView.RecordCount) 'Still equals 4, normal
Console.WriteLine(filtersView.BOF) 'False, normal
Console.WriteLine(filtersView.EOF) 'True, which is NOT normal
Console.WriteLine(filtersView.AbsolutePosition) 'Get -3 not sure why (position 1 related to 4???)
Console.WriteLine(filtersView.MaxRecords) 'Get 0 not sure why
sTemp = sTemp & "(" & dataView(0, i).ToString & ", " & dataView(1, i).ToString & ")"
filtersView.MoveNext() '!!!! Here is where it fails !!!! Cannot go more than i=0
Next i
Console.WriteLine(sTemp)
You can verify that by checking the value of filtersView.AbsolutePosition immediately before and after your call to GetRows
Also, you are reversing rows and columns in dataView, move i to the second subscript position. I put it in a temporary string to make it easier to view in the debugger.
I have a Database that I need to use, but it has some errors which I have to fix.
Since I am not an expert in MS-Access, I can not figure out where the mistakes are.
The first error
Run-time. Could not find field '| 1' to which reference is made in the expression.
is thrown when pressing the print button.
Opening the debug, I found this piece of code:
Private Sub Pulsante40_Click()
If Me!Campo51 = False Then
Select Case [schede]![S_Stampa_Ordini].[ordinamento]
Case 1
DoCmd.OpenReport "Stampa Ordini BY DATA", , , " (DATA_AGG Between #" & Format$(Me.[Dal], "mm/dd/yyyy") & "# And #" & Format$(Me.[Al], "mm/dd/yyyy") & " 23:59#) AND Tipo = """ & Me.TipoL & """"
Case 2
DoCmd.OpenReport "Stampa Ordini BY CLIENTE", , , " (DATA_AGG Between #" & Format$(Me.[Dal], "mm/dd/yyyy") & "# And #" & Format$(Me.[Al], "mm/dd/yyyy") & " 23:59#) AND Tipo = """ & Me.TipoL & """"
Case 3
DoCmd.OpenReport "Stampa Ordini BY LAVORAZION", , , " (DATA_AGG Between #" & Format$(Me.[Dal], "mm/dd/yyyy") & "# And #" & Format$(Me.[Al], "mm/dd/yyyy") & " 23:59#) AND Tipo = """ & Me.TipoL & """"
Case 4
DoCmd.OpenReport "Stampa Ordini BY DATA_CONS", , , " (DATA_AGG Between #" & Format$(Me.[Dal], "mm/dd/yyyy") & "# And #" & Format$(Me.[Al], "mm/dd/yyyy") & " 23:59#) AND Tipo = """ & Me.TipoL & """"
End Select
FDipendente = 0
Else
DoCmd.OpenForm "FiltroStampa", , , , , A_DIALOG
End If
End Sub
It gives me error on line:
Select Case [schede]![S_Stampa_Ordini].[ordinamento]
The second error
Compile Error, could not find the method or data member
is thrown when I open the mask minutes and select
Legno, or Lavorazione Ext
code:
Private Sub Tipo_AfterUpdate()
Select Case Me.Tipo
Case "C"
Me.[SSMin-In].scheda.testo0.Caption = "Lavorazione:"
Case "L"
Me.[SSMin-In].scheda.testo0.Caption = "Cod.Prev.:"
Case "E"
Me.[SSMin-In].scheda.testo0.Caption = "Cod.Prev.:"
End Select
End Sub
It gives me the error on line:
Private Sub Tipo_AfterUpdate()
It has been days that I'm trying to solve the Database, or at least to start studying the visual basic to understand something. Unfortunately I only know java and my colleagues can not help me. Thank you in advance for an answer and I apologize if I was unclear or did not provide enough information.
It looks to me like your code is trying to refer to controls on your form, but in an invalid way (I can't quite understand what the code is trying to do because I don't read the language, and I don't know what controls you have on the form).
For example, to get the value of a combo box on a form, you would normally type something like Me.cboMyCombo.Value. To get the value of a field bound to this form, you would type something like Me!MyField or Me![My Field].Value.
Your calls to [schede]![S_Stampa_Ordini].[ordinamento] and Me.[SSMin-In].scheda.testo0.Caption look like they have a few too many methods on the end.
One way to find out what methods are acceptable is to start typing and let the pop-up menus guide you. For example, type Me. and see what pops up. In my example, cboMyCombo would be one of the items in the menu. Choose it, and you will see a new menu with Value as a choice.
You can also use the 'Expression Builder'.
You might want to try to copy your SQL into a query (or two). Make sure they actually produce the results you want. Then, you can call DoCmd.OpenQuery "qappYourNewQueryName". It is easier to read.
INSERT INTO [MIN-OUT]
( LAVORAZION, TIPO, MINUTI )
SELECT DISTINCTROW
[MIN-IN].LAVORAZION,
[MIN-IN].TIPO,
0 FROM [MIN-IN]
GROUP BY
[MIN-IN].LAVORAZION,
[MIN-IN].TIPO;
' What is this?
, ID_Dipendente )
SELECT DISTINCTROW
[MIN-IN].LAVORAZION,
[MIN-IN].TIPO,
[Forms]![Minuti].[dipendente] AS Espr1
FROM [MIN-IN]
GROUP BY
[MIN-IN].LAVORAZION,
[MIN-IN].TIPO,
[Forms]![Minuti].[dipendente];")
I have the following ASP code below which is used within a import from a .csv file. I am getting the error on line
rs_add_pg_asset_attr("level_3_integer_attribute_description") = rs_get_costs("sp_import_pg_attribute_value")
I'm guessing the code is trying to set 2 columns in two different recordsets to be equal to the same thing? Correct me if I'm wrong. The data in level_3_integer_attribute_description is type decimal(13,3), NULL and the data in sp_import_pg_attribute_value is a whole range of different values type varchar(255), NULL.
I cannot work out why this is failing.
str_get_pg_attribute_id_sql = "SELECT * FROM tbl_level_3_cbs_attribute WHERE level_3_cbs_attribute_description = '" & rs_get_costs("sp_import_pg_attribute") & "'"
str_get_pg_attribute_id_sql = str_get_pg_attribute_id_sql & " AND level_3_cbs_id = " & int_level_3_id
rs_get_pg_attribute_id.Open str_get_pg_attribute_id_sql, dbConnection, 3
if rs_get_pg_attribute_id.RecordCount <> 0 then
''//Does the attribute already exist?
str_get_pg_attribute_sql = "SELECT * FROM tbl_asset_level_3_attribute_link WHERE "
str_get_pg_attribute_sql = str_get_pg_attribute_sql & "level_3_cbs_attribute_id = " & rs_get_pg_attribute_id("level_3_cbs_attribute_id") & " AND asset_level_3_id = " & int_pg_asset_id
rs_get_pg_attribute.Open str_get_pg_attribute_sql, dbConnection, 3
if rs_get_pg_attribute.RecordCount = 0 then
''//No, add the attribute record
sqlString="select top 1 * from tbl_asset_level_3_attribute_link"
rs_add_pg_asset_attr.Open sqlString, dbConnection, adOpenKeyset, adLockOptimistic
rs_add_pg_asset_attr.AddNew
rs_add_pg_asset_attr("level_3_cbs_attribute_id") = rs_get_pg_attribute_id("level_3_cbs_attribute_id")
rs_add_pg_asset_attr("asset_level_3_id") = int_pg_asset_id
if rs_get_pg_attribute_id("level_3_cbs_attribute_type") = "I" then
rs_add_pg_asset_attr("level_3_integer_attribute_description") = rs_get_costs("sp_import_pg_attribute_value")
else
rs_add_pg_asset_attr("level_3_string_attribute_description") = rs_get_costs("sp_import_pg_attribute_value")
end if
Are you sure that level_3_integer_attribute_description is an existing field name, no typo error anywhere ?
If so, is the data you want to put into this decimal value, a correct string representation of a floating value ? No problems with decimal points and comma's ?
Since the error is a Type Mismatch error, you probably have a type mismatch error :)
Try this:
rs_add_pg_asset_attr("level_3_integer_attribute_description") = _
tryCDbl( rs_get_costs("sp_import_pg_attribute_value"))
and then:
function tryCDbl( something )
dim retval
retval = 0 ''// fallback
on error resume next
if isNumeric( something ) then
retval = cdbl( something)
end if
tryCDbl = retval
end function
We found the answer to this question. The problem was the Import was trying to assign a blank space into a decimal column. Thanks for your help. I'm stuck on something else now!