Automapper with Anonymous list in VB.Net - vb.net

I'm having a problem getting Automapper to work correctly with Lists of anonymous types VB.Net. I've found a few examples on-line in C# but cannot get them to compile let alone work once converted to VB.Net. Code below is a simplified version of what I am trying to do. The errors I am getting with the code below are "Type argument cannot be inferred from usage" on the select and "Incorrect number of arguments" in DynamicMap but I have tried loads of variations each fixes one problem and creates at least one more.
Any help would be much appreciated as I have been looking at this for over a day.
Public Function OrgList() As List(Of OrganisationListSelectVm)
Dim orgs = (From o In EntityModel.Organisations
Join r In EntityModel.Regions On o.RegionID Equals r.RegionID
Order By o.OrganisationName
Select
o.OrganisationID,
o.OrganisationName,
o.OrganisationCode,
o.RegionID,
r.RegionName).ToList()
'** mapping one item works fine
Dim oneItem = Mapper.DynamicMap(Of OrganisationListSelectVm)(orgs(0))
'** C# mapper from various web sites
'var result = orgs.Select(Mapper.DynamicMap<OrganisationListSelectVm>).ToList();
'** VB converted type which fails
Dim result As List(Of OrganisationListSelectVm) = orgs.[Select](Mapper.DynamicMap(Of OrganisationListSelectVm)).ToList()
Return result
End Function

Related

LINQ Count problems while trying to access to subList from a List of Objects (VB.NET)

I'm having a pretty tough time figuring it out why it doesn't work properly but I'm asking for it.
Dim goodCount As Integer = (From item In equipmentTagList
Where item.Importance = "Critique"
Where item.Status <> TargetRange.OutOfRange
Select item).Count()
Dim badCount As Integer = (From item In equipmentTagList
Where item.Importance = "Critique"
Where item.Status.Contains(TargetRange.OutOfRange)
Select item).Count()
EquipmentTagList is a List(Of MachineTag) (custom object) so I want to get how many MachineTag from the EquipmentTagList matches the criteria. I'm still confused about why the first one works but not the other one. I know by debugging that the first one returns at least one result while the other returns nothing... I've searched a lot to get help for this error but unfortunately found nothing...
Thanks for helping me out.
EDIT:
The error I get is :
System.InvalidOperationException with Object reference not set to an instance of an object
Assuming for the moment that item.Status is an Integer data type (inferred from your use of TargetRange.OutOfRange as though it's an Enum), the syntax in your second snippet would be expected to fault.
The .Contains() method is reserved for use with IEnumerable objects, not Integer values.
If you modify your code slightly, to this:
Dim badCount = (From item In equipmentTagList
Where item.Importance = "Critique"
Where item.Status.Contains(TargetRange.OutOfRange)
Select item)
...and then set a breakpoint at some point after this call, you'll note that badCount is Nothing. Since Nothing can't have a .Count, the call fails.
Your first snippet is correct—as you've already pointed out.
EDIT
Something's not right here. Your code shouldn't even compile.
Here's what I'm getting:
So item.Status certainly can't be an Integer.
Maybe this will make it a bit easier. You can group by Status after filtering by Importance:
Dim items = From i In equipmentTagList Where i.Importance = "Critique"
Dim counts = items.ToLookup(Function(i) i.Status <> TargetRange.OutOfRange)
Dim goodCount = counts(True).Count()
Dim badCount = counts(False).Count()

Excel Automation Addin - functions not working

Edit: The real solution to what I wanted to do can be found on this post here. I just wanted to expose some compiled functions to excel. This proved to be very easy using the Excel DNA nuget package. You just add a class library, add the nuget package, and copy paste the code found in the readme. Click F5 and it launches excel with the add-in already loaded. If you want your functions to be persisted you just need to manually add the add-in to the excel file through the "developer" ribbon section.
Original Post:
I was following the instructions from this microsoft post on how to create an automation add-in. Code compiles fine and I can access the functions from within Excel. However the functions do not work. I almost always get a #value or a #ref error when I try to assign to a cell the result of a function call. To be more specific:
The following function that is provided by Microsoft does not work. It shows me a #value error in the cell where I try to use it. I select using the mouse a random cell range as a parameter for the function.
Public Function NumberOfCells(ByVal range As Object) As Double
Dim r As Excel.Range = TryCast(range, Excel.Range)
Return CDbl(r.get_Cells.get_Count)
End Function
The following function that I created does not work. I get a #ref error. I called it by passing either directly integers ( Add1(1,2) ) or cells that contain numbers.
Public Function Add1(ByVal i1 As Integer, ByVal i2 As Integer) As Integer
return i1+i2
End Function
The following function that I created works(?!?):
Public Function Add1(ByVal i1 As Integer, ByVal i2 As Integer) As Integer
return 222
End Function
I am quite experienced in c# but not at all in vb.net, however for this add-in I need to use vb.net. I suspect that there is something simple that I am missing here but I have no idea what it is. It is also strange that the code provided by Microsoft doesn't work.
Edit: I also copy pasted the function presented here and I get the same #Value error inside excel. I did not follow the tutorial from this post from the beginning but I will during the day.
Edit 2: I figured out that the code from Microsoft doesn't work for some reason whenever you add a number in the function name. If I renamed Add1 on the sample code above to Addqweqew it would work!
MSDN Ref: http://blogs.msdn.com/b/andreww/archive/2008/01/23/managed-automation-add-ins.aspx
It has to do with a locale ID (LCID) issue. This is a known issue when
developing Excel solutions in a mixed culture environment. For more
information, see here: http://support.microsoft.com/kb/246501/.
VSTO solves this problem via its LCID Proxy. Although you can only use
this with VSTO solutions, its worth reading the documentation so you
can understand the problem:
http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.excellocale1033proxy.aspx
and
http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.excellocale1033attribute.aspx.
I got the same problem #Value results, I mucked around a bit and got this working (obviously it could be cleared up - but this code definitely works for me while keeping my PC set to my Australian locale ID. I'm not sure which part of the world you live but I am guessing not the United States as that's the locale where it works by default)
Public Function AddNumbers1(ByVal num1 As Double, _
ByVal num2 As Double) As Double
Dim oldCI As CultureInfo = Thread.CurrentThread.CurrentCulture
Dim english As System.Globalization.CultureInfo = System.Globalization.CultureInfo.GetCultureInfo("en-US")
System.Threading.Thread.CurrentThread.CurrentCulture = english
System.Threading.Thread.CurrentThread.CurrentUICulture = english
Dim valresult As Double = num1 + num2
Thread.CurrentThread.CurrentCulture = oldCI
Return valresult
End Function
Related question: https://social.msdn.microsoft.com/Forums/en-US/dafe71c5-d390-44bc-b4d3-b133444a02fe/excel-automation-addin-udf-returns-error-on-different-regional-settings?forum=vsto

Reading and changing fields in SAP with RFC via VB .NET

I'm currently trying to figure out the basics of remote function calls via vb .NET. I feel pretty helpless however, because their just isn't any useful documentation for the most simple of tasks.
What I'm trying to do atm is starting the transaction CO13, write the confirmation number in the appropriate field and cancel the order. Even this simple tasks turned out to be a pain in the ass. I'm still not sure how to access and modify the contents of a specific field. There are some examples with tables for excel in the net, but hat's about it. What I have so far is this (login is working and in another function):
Public Function stornieren() As Boolean
Dim ordernr As String
Dim confirmationnr
Dim confirmation As Object
Dim R3 As Object
Dim CO13 As Object
Dim result
R3 = CreateObject("SAP.Functions")
ordernr = TextBox3.Text
confirmationnr = TextBox4.Text
CO13 = R3.Add("RFC_CALL_TRANSACTION_USING")
CO13.exports("TCODE") = "CO13"
CO13.exports("MODE") = "S"
confirmation = CO13.exports("RUECK")
confirmation.value = confirmationnr
result = CO13.call
End Function
RUECK is the Field Name. I want to write the value of "confirmationnr" into the field RUECK. "confirmation.value = confirmationnr" throws the error message "the object variable could not be determined" and "NullReferenceException" was not handled. Sounds to me like the object is empty.
Thanks in advance.
EDIT: Now trying via BAPIs and particularly BAPI_PRODORDCONF_CANCEL. I have no idea about the syntax though. Any help would be appreciated.

facebook c# SDK vb.net issue

i have been trying to use this sdk with vb.net with dynamic, using the vb sample thats on the site and im getting an error
"Public member 'id' on type 'JsonObject' not found."
thats in the sample GetSampleWithAccessToken referring to is
Dim id = result.id
You're giving too little context, but it seems that result is typed as JsonObject, while it should be typed explicitly as Object for the dynamic features of VB to kick in.
Dim result as Object = ...
Dim id = result.id

Linq to Datarow, Select multiple columns as distinct?

basically i'm trying to reproduce the following mssql query as LINQ
SELECT DISTINCT [TABLENAME], [COLUMNNAME] FROM [DATATABLE]
the closest i've got is
Dim query = (From row As DataRow In ds.Tables("DATATABLE").Rows _
Select row("COLUMNNAME") ,row("TABLENAME").Distinct
when i do the above i get the error
Range variable name can be inferred
only from a simple or qualified name
with no arguments.
i was sort of expecting it to return a collection that i could then iterate through and perform actions for each entry.
maybe a datarow collection?
As a complete LINQ newb, i'm not sure what i'm missing.
i've tried variations on
Select new with { row("COLUMNNAME") ,row("TABLENAME")}
and get:
Anonymous type member name can be
inferred only from a simple or
qualified name with no arguments.
to get around this i've tried
Dim query = From r In ds.Tables("DATATABLE").AsEnumerable _
Select New String(1) {r("TABLENAME"), r("COLUMNNAME")} Distinct
however it doesn't seem to be doing the distinct thing properly.
Also, does anyone know of any good books/resources to get fluent?
You start using LINQ on your datatable objects, you run the query against dt.AsEnumberable, which returns an IEnumerable collection of DataRow objects.
Dim query = From row As DataRow In ds.Tables("DATATABLE").AsEnumerable _
Select row("COLUMNNAME") ,row("TABLENAME")
You might want to say row("COLUMNNAME").ToString(), etc. Query will end up being an IEnumerable of an anonymous type with 2 string properties; is that what you're after? You might need to specify the names of the properties; I don't think the compiler will infer them.
Dim query = From row As DataRow In ds.Tables("DATATABLE").AsEnumerable _
Select .ColumnName = row("COLUMNNAME"), .TableName = row("TABLENAME")
This assumes that in your original sql query, for which you used ADO to get this dataset, you made sure your results were distinct.
Common cause of confusion:
One key is that Linq-to-SQL and (the Linq-to-object activity commonly called) LINQ-to-Dataset are two very different things. In both you'll see LINQ being used, so it often causes confusion.
LINQ-to-Dataset
is:
1 getting your datatable the same old way you always have, with data adapters and connections etc., ending up with the traditional datatable object. And then instead of iterating through the rows as you did before, you're:
2 running linq queries against dt.AsEnumerable, which is an IEnumerable of datarow objects.
Linq-to-dataset is choosing to (A) NOT use Linq-to-SQL but instead use traditional ADO.NET, but then (B) once you have your datatable, using LINQ(-to-object) to retrieve/arrange/filter the data in your datatables, rather than how we've been doing it for 6 years. I do this a lot. I love my regular ado sql (with the tools I've developed), but LINQ is great
LINQ-to-SQL
is a different beast, with vastly different things happening under the hood. In LINQ-To-SQL, you:
1 define a schema that matches your db, using the tools in in Visual Studio, which gives you simple entity objects matching your schema.
2 You write linq queries using the db Context, and get these entities returned as results.
Under the hood, at runtime .NET translates these LINQ queries to SQL and sends them to the DB, and then translates the data return to your entity objects that you defined in your schema.
Other resources:
Well, that's quite a truncated summary. To further understand these two very separate things, check out:
LINQ-to-SQL
LINQ-to-Dataset
A fantastic book on LINQ is LINQ in Action, my Fabrice Marguerie, Steve Eichert and Jim Wooley (Manning). Go get it! Just what you're after. Very good. LINQ is not a flash in the pan, and worth getting a book about. In .NET there's way to much to learn, but time spent mastering LINQ is time well spent.
I think i've figured it out.
Thanks for your help.
Maybe there's an easier way though?
What i've done is
Dim comp As StringArrayComparer = New StringArrayComparer
Dim query = (From r In ds.Tables("DATATABLE").AsEnumerable _
Select New String(1) {r("TABLENAME"), r("COLUMNNAME")}).Distinct(comp)
this returns a new string array (2 elements) running a custom comparer
Public Class StringArrayComparer
Implements IEqualityComparer(Of String())
Public Shadows Function Equals(ByVal x() As String, ByVal y() As String) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of String()).Equals
Dim retVal As Boolean = True
For i As Integer = 0 To x.Length - 1
If x(i) = y(i) And retVal Then
retVal = True
Else
retVal = False
End If
Next
Return retVal
End Function
Public Shadows Function GetHashCode(ByVal obj() As String) As Integer Implements System.Collections.Generic.IEqualityComparer(Of String()).GetHashCode
End Function
End Class
Check out the linq to sql samples:
http://msdn.microsoft.com/en-us/vbasic/bb688085.aspx
Pretty useful to learn SQL. And if you want to practice then use LinqPad
HTH
I had the same question and from various bits I'm learning about LINQ and IEnumerables, the following worked for me:
Dim query = (From row As DataRow In ds.Tables("DATATABLE").Rows _
Select row!COLUMNNAME, row!TABLENAME).Distinct
Strangely using the old VB bang (!) syntax got rid of the "Range variable name..." error BUT the key difference is using the .Distinct method on the query result (IEnumerable) object rather than trying to use the Distinct keyword within the query.
This LINQ query then returns an IEnumerable collection of anonymous type with properties matching the selected columns from the DataRow, so the following code is then accessible:
For Each result In query
Msgbox(result.TABLENAME & "." & result.COLUMNNAME)
Next
Hoping this helps somebody else stumbling across this question...