NullReferenceException when retrieving values from LINQ to DataTable - linq

I have an application that is loading data into a database in a background task. The values are retrieved from a datatable using LINQ, manipulated and stored in a new datatable. I'm getting a NullReferenceException error and I can't figure out why. I'm checking to see if the value coming from the LINQ query is null, and if it is, the variable is assigned properly. If, however, the LINQ query contains a value, I get a NullReferenceException "Object reference not set to an instance of an object" error which really makes no sense to me. What am I doing wrong?
Dim pin = (From u In partdata.AsEnumerable() _
Where u.Field(Of String)("PART_GRP") = sPartType And
u.Field(Of String)("INVT_TYPE").Contains("A")
Select oid = u.Field(Of String)("ID"), Position = u.Field(Of Integer?))
Dim pout = (From u In partdata.AsEnumerable() _
Where u.Field(Of String)("PART_GRP") = sPartType And
u.Field(Of String)("INVT_TYPE").Contains("B") Or u.Field(Of String)("INVT_TYPE").Contains("C")
Select oid = u.Field(Of String)("ID"), Position = u.Field(Of Integer?))
If pin.Count > 0 And pout.Count > 0 Then
For i = 0 To pout.Count - 1
ioidID = pout(i).oid
' Parts In
If pin(i).Position Is Nothing Then ' When "Position" is Null, it works and "" is assigned. When "position" is not null, I get a NullReferenceException error on this line.
spinPosition = ""
Else
spinPosition = pin(i).Position
End If
...

Based on the comments to the question, it appears that pin(i) is Nothing. This would cause the exception when you try to dereference it here:
pin(i).Position
Note that you define pin and pout as two separate collections, unrelated to one another. You check that they both contain at least one value:
If pin.Count > 0 And pout.Count > 0 Then
But you never check that they contain the same number of values. You assume this here:
For i = 0 To pout.Count - 1
If pout ever contains more values than pin, your code will fail.

Related

Querying in MS Access 2013 excluding special characters

I am trying to create an update query in MS Access where I will pull a few fields of information from one table if one of the fields matches and the rest are blank. For example:
**Table 1**
SKU Description Weight Lead Time
C210657 NULL NULL NULL
221AB0909 NULL NULL NULL
VA12345 NULL NULL NULL
221AB09 NULL NULL NULL
**Table 2**
SKU Description Weight Lead Time
F-210-223.2 Hammer 2.1 3.1
201-ABF-345 Car 12546.0 65.0
C_210657 Apple 0.2 1.0
34_AA_332 Puppy 5.5 55.0
221 AB 0909 Stereo 12.0 875.0
VA12345_123-A Labor 0.0 0.0
So I want the query to fill in columns 2 through 4 of table 1 with information from table 2. All four of the items in table 1 have a match in table 2, there are just special characters (-, _, ., ), that are in the way. How can I have the query ignore them? Thanks
Which way you go depends on what you're willing to do. If it's a big database, you might want to add a new field [SKU_Index] that is SKU with the special characters removed and link on that.
If that's not a possibility, then you can do a calculated subquery and link on the calculated field...but it can be a little slow.
You would need to write a procedure that removes the special characters from a passed string. Let me know if you would like help with that.
Then you do a query on Table 2 like this:
Select SKU2:RemoveSpecialChars([SKU]), Description, Weight, [Lead Time] From [Table 2];
RemoveSpecialChars() would be your procedure.
You save that query (let's call it PreQuery). Create a new query and bring in PreQuery and Table 1 linking SKU from Table 1 to SKU2 from PreQuery, and update the relevant fields.
Ideally, cause storage is cheap, I would keep a second field without the special characters and perhaps index on it.
Here's example code for how that would work:
Public Function RemoveSpclChars(strIn As String) As String
' Comments : removes any special characters
' Parameters: strIn - string to check
' Returns : resulting string with removed special characters, can be empty
'
Dim lngCounter, intChar As Integer
Dim chrTmp As String * 1
Dim strTmp As String
On Error GoTo PROC_ERR
strTmp = ""
' Walk through the string
For lngCounter = 1 To Len(strIn)
' Get the current character
chrTmp = Mid$(strIn, lngCounter)
intChar = Asc(chrTmp)
' Test if alpha or numeric only
If (intChar >= Asc("a") And intChar <= Asc("z")) Or (intChar >= Asc("0") And intChar <= Asc("9")) Then
strTmp = strTmp & chrTmp
End If
Next lngCounter
PROC_EXIT:
RemoveSpclChars = strTmp
Exit Function
PROC_ERR:
Dim strErr As String
strTmp = "ERROR: " & Trim(Str(Err.Number)) & ":" & Err.Description
Resume PROC_EXIT
End Function

Unable to create a constant value - only primitive types or Enumeration types allowed

I have seen some questions related to this Exception here but none made me understand the root cause of the problem. So here we have one more...
var testquery =
((from le in context.LoanEMIs.Include("LoanPmnt")
join lp in context.LoanPmnts on le.Id equals lp.LoanEMIId
where lp.PmntDtTm < date && lp.IsPaid == false
&& le.IsActive == true && lp.Amount > 0
select new ObjGetAllPendingPmntDetails
{
Id = lp.Id,
Table = "LoanEMI",
loanEMIId = lp.LoanEMIId,
Name = le.AcHead,
Ref = SqlFunctions.StringConvert((double)le.FreqId),
PmntDtTm = lp.PmntDtTm,
Amount = lp.Amount,
IsDiscard = lp.IsDiscarded,
DiscardRemarks = lp.DiscardRemarks
}).DefaultIfEmpty(ObjNull));
List<ObjGetAllPendingPmntDetails> test = testquery.ToList();
This query gives the following Exception Message -
Unable to create a constant value of type CashVitae.ObjGetAllPendingPmntDetails. Only primitive types or enumeration types are supported in this context.
I got this Exception after I added the SQL function statement to convert le.FreqId which is a byte to a string as ToString() is not recognized in the LINQ Expression Store.
ObjGetAllPendingPmntDetails is a partial class in my model which is added as it is used too many times in the code to bind data to tables.
It has both IDs as long, 'Amount' as decimal, PmntDtTm as Datetime,IsDiscard as bool and remaining all are string including 'Ref'.
I get no results as currently no data satisfies the condition. While trying to handle null, I added DefaultIfEmpty(ObjNull) and ObjNull has all properties initialized as follows.
ObjGetAllPendingPmntDetails ObjNull = new ObjGetAllPendingPmntDetails()
{ Id = 0, Table = "-", loanEMIId = 0, Name = "-", Ref = "-",
PmntDtTm = Convert.ToDateTime("01-01-1900"),
Amount = 0, IsDiscard = false, DiscardRemarks = "" };
I need this query to work fine as it has Union() called on it with 5 other queries. All returning the same ObjGetAllPendingPmntDetails columns. But there is some problem as this query has no data satisfying the conditions and the Exception Shared Above.
Any suggestions are appreciated as I am unable to understand the root cause of the problem.
#AndrewCoonce is right, the .DefaultIfEmpty(ObjNull) is the culprit here. Entity Framework turns DefaultIfEmpty into something like...
CASE WHEN ([Project1].[C1] IS NULL) THEN #param ELSE [Project1].[Value] END AS [C1]
...but there's no way to coerce an instance of ObjGetAllPendingPmntDetails into something that can take the place of #param, so you get an exception.
If you move the DefaultIfEmpty call to after the ToList it should work correctly (although you'll need to call ToList again after that if you really want a concrete list instance).

Lotus Notes 7 - Auto-calculation for one column from an editable view - InViewEdit event

I have a problem that gives me some headaches lately. I hope I can find a solution with your help.
I have a view : "vwTest" which is embedded on a form. It is an editable view. The view has 3 columns: Number , Cost , Difference. All the 3 columns have as their default values some field names which exist on a form called "fmTest", the field names are: Number , Cost , Difference.
On the main form ( which contains the view ) there is a field ( computed ) called: TotalValue.
The view has 2 actions: AddLine and DeleteLine.
What I want to do is:
Let say TotalValue = 5000
user complete the first line of the view:
Number | Cost | Difference
1 | 50 | 4950 => The 3rd column value to be calculated automatically as the difference between 5000 ( TotalValue ) and 50 ( the value of the 2nd column )
user complete the second line of the view:
2 | 60 | 4890 => the 3rd column value to be calculated automatically as the difference between the last 3rd column value from the view and 60 ( the current value of the 2nd column )
I think that's like a recursive algorithm.
The value of TotalValue exists, it is a Number type field.
Hope to find a solution and resolve this problem! I really appreciate your help and time!
After every save you have to cylce through all entries belonging to "this" main document and recalculate the totals. I assume, that the "lines" are response- documents to the main document and that the Embedded view is categorized by the unid of the main document...
Dim ses as New NotesSession
Dim db as NotesDatabase
Dim viewEmbedded as NotesView
Dim viwNav as NotesViewNavigator
Dim ve as NotesViewEntry
Dim docLine as NotesDocument
Dim docMain as NotesDocument
Dim dblTotal as Double
Set db = ses.CurrentDatabase
Set docMain = ... 'somehow get the main document, therefor I would need your current code
dblTotal = docMain.TotalValue(0)
Set viewEmbedded = db.Getview( "vwTest" )
viewEmbedded.AutoUpdate = False
Set viwNav = viwEmbedded.CreateViewNavFromCategory( docMain.UniversalID )
Set ve = viwNav.getFirst()
While Not ve is Nothing
Set docLine = ve.Document
dblTotal = dblTotal - docLine.Cost(0)
If dblTotal <> docLine.Difference(0) then
docLine.Difference = dblTotal
Call docLine.Save( true, true )
End If
Set ve = viwNav.getnextDocument(ve)
Wend
Why the loop? What if someone modifies the first line after a second one and a third one have been created? then the total for 2, 3 and all subsequent lines has to change.
This code was not typed in Designer and might contain typos. It does NOT contain any error- handling and can produce Replication / Save- Conflicts if not used carefully..
Hope that helps

compare datatable and remove duplicates in vb.net

am using two datatable named as dnddatatable and dtdup . it contains set of phone numbers . I want to compare 2nd datatable with first datatable and remove the values from datatable1(name as dnddatatable)values which are equal to 2nd datatable name as(dtdup).
data in the datatable as follows.
dnddatatable(data table1)
phone
9865015695
9840903331
98668625
800971868
809679532
837445478
dtdup(dtata table2)
phone_numbers
9865015695
9840903331
result dnddatatable(data table1)
98668625
800971868
809679532
837445478
I answered a pretty similar question time ago, the idea is exactly the same
For i As Integer = 0 To dataset.Tables(0).Rows.Count - 1
Dim found As Boolean = False
For j As Integer = 0 To dataset1.Tables(0).Rows.Count - 1
If dataset.Tables(0).Rows(i)(0).ToString = dataset1.Tables(0).Rows(j) (0).ToString Then
found = True
End If
Next
If found = False Then
'here you are getting the right result in each loop
'in this example i'm showing the result in a textbox
'just change the instruction and write them in your note pad or wherever you want to
MsgBox(dataset.Tables(0).Rows(i)(0).ToString)
End If
Next

Make only one row show after search in FlexGrid VB6

So i have FlexGrid in my VB6 project I'm working on. It has names on each row, and I have a drop down so the user can select what name they want to see more info for, here is what I have.
Dim target_name As String
Dim r As Integer
' Get the name.
target_name = Combo1
If Len(target_name) = 0 Then Exit Sub
' Search for the name, skipping the column heading row.
target_name = LCase$(target_name)
For r = 1 To MSFlexGrid1.Rows - 1
If LCase$(MSFlexGrid1.TextMatrix(r, 0)) = _
target_name Then
' We found the target. Select this row.
MSFlexGrid1.Row = r
MSFlexGrid1.RowSel = r
MSFlexGrid1.Col = 0
MSFlexGrid1.ColSel = MSFlexGrid1.Cols - 1
' Make the row visible.
MSFlexGrid1.TopRow = r
Exit Sub
End If
Next r
That works well, but it shows everything below that name too, I would like it to single out only the name selected.
Any help would be great.
What's the data source of your grid? You can place the filter on the data grid data source, so that as the user chooses the name from your drop down only the selected persons details are returned from the datasource to the grid.
Not exactly what you were asking, but its how I would achieve the result you are wanting.
P.S. I have used FlexGrid in VB6 and I don't know of a way to do what you are asking on the grid (might be there but I never noticed it).

Resources