Hi this is my first post so hello everybody,

I've recently been exploring the uses of linq
to use for comparisons,but really need a bit of a kickstart.

Say for instance i have a listview populated with numbered names
and I want to put up a message box if certain conflicts arise

such as this:-


This string combination is ok:-

1 fred

1 fred

2 fred

4 barney

5 wilma

5 wilma

6 barney

6 barney

This string combination is Not:-

1 fred (!! conflict - 1 is already used )

1 barney (!! conflict - 1 is already used )

3 dino

2 barney (!! conflict - 2 is already used )

4 pebbles

6 betty

2 wilma (!! conflict - 2 is already used )

etc,etc


So to summarize, the prefix number can only have one unique name assigned to it,

and that unique combo can be used as often as you like.

I come across this type of critera all the time and am yet to
come up with a solution,maybe Linq could be the answer.

Thanks in advance for any help

Best Regards

Enjoy

Public Class Form1


  Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        ListView1.Items.Add("1 Fred")
        ListView1.Items.Add("1 Barney")
        ListView1.Items.Add("3 Dino")
        ListView1.Items.Add("2 Barney")
        ListView1.Items.Add("4 Pebbles")
        ListView1.Items.Add("6 Betty")
        ListView1.Items.Add("2 Wilma")
        ListView1.Items.Add("40 WD")
        ListView1.Items.Add("40 WD")
        ListView1.Items.Add("40 WD")
        ListView1.Items.Add("4 Pebbles")
    End Sub

    Private Sub ButtonFindConflicts_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonFindConflicts.Click

        Dim Conflicts = From ListItem As ListViewItem In ListView1.Items _
                        Select Name = ListItem.Text _
                        Distinct _
                        Group By ConflictedGroup = Name.Substring(0, Array.IndexOf(Name.ToCharArray, " "c)) _
                        Into DuplicatedNumbers = Group, Count() _
                        Where (Count > 1)

        If Conflicts.Count > 0 Then
            Dim Message As String = "The Following Conflicts Have Occured" & vbCrLf

            For Each ConflictedGroup In Conflicts
                Message &= vbCrLf
                For Each DuplicatedName As String In ConflictedGroup.DuplicatedNumbers
                    Message &= vbTab & DuplicatedName & vbCrLf
                Next
            Next

            MsgBox(Message, MsgBoxStyle.OkCancel, "linqed it")
        End If
    End Sub
End Class

It first gets a distinct list of the listviewItems text then groups them by the number the text starts with then eliminates groups who only have a count of 1.

Hey,Thanks a lot for that,it worked great!
Now say for instance These numbers & names had been split
into subitem columns.
How would you code for this scenario?

You can control which items are used in the Select part.

If the number is in the first subitem and the name in the 2 then you could do this.

Dim Conflicts = From ListItem In ListView1.Items _
                Select Number = CType(ListItem, ListViewItem).SubItems(0).Text, _
                       Name = CType(ListItem, ListViewItem).SubItems(1).Text _
                Distinct _
                Group By ConflictedGroup = Number _
                Into DuplicatedNumbers = Group, Count() _
                Where (Count > 1)

If Conflicts.Count > 0 Then

     Dim Message As String = "The Following Conflicts Have Occured" & vbCrLf
     For Each ConflictedGroup In Conflicts

          Message &= vbCrLf
          For Each DuplicatedName In ConflictedGroup.DuplicatedNumbers
               Message &= vbTab & DuplicatedName.Number & " " & DuplicatedName.Name & vbCrLf
          Next
     Next
     MsgBox(Message, MsgBoxStyle.OkCancel, "linqed it")

End If

Edited 5 Years Ago by Unhnd_Exception: n/a

So Sorry to bother you again Unhnd_Exception,
But I seem to be having a problem using the Linq code in my application.
I made a temp application to try the code out and everthing worked great,
but as I mention when I took the code and typed (not copied & Pasted)
I'm getting an error.
If I hover over the 'Conflicts' of 'If Conflicts.Count > 0 Then' of
the temp application I get the popup box stating ,

Dim Collections as System.Collections.Generic.IENumerable(Of <anonymous type>

)

yet in my application this has changed to,

Dim Conflicts As Object,

This is throwing an error at,

For Each ConflictedGroup In Conflicts

I've added in the Linq Namespace with no luck.
Any Ideas as to how I can solve this?

Post the linq code you typed up.

The Imports

Imports VB = Microsoft.VisualBasic
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.IO
Imports System.Diagnostics
Imports PowerSolutionDOTNetOLE.clsPowerMILLOLE
Imports PMILL = PowerSolutionDOTNetOLE.clsPowerMILLOLE
Imports System.Threading
Imports System.Text.RegularExpressions
Imports System.Runtime.InteropServices
Imports System.Reflection
Imports System.Collections
Imports System.Linq

And this in the Load event

Public Class Form1
    Dim strProjectPath As String
    Dim strProjectName As String
    Dim strProgramPath As String
    Dim toolTipRadius As String
    Dim toolDiameter As Integer
    Dim toolDrillAngle As Integer
    Dim intUnits As Integer
    Dim sortColumn As Integer = -1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Load, Button2.Click

        Me.Cursor = Cursors.WaitCursor
        Dim pm As PowerMILL.Application = GetObject(, "PowerMILL.Application")
        If IsNothing(pm) Then
            MessageBox.Show("Ensure PowerMILL is running")
            Return
        End If

       
        Dim tps As PowerMILL.Toolpaths = pm.Project.Toolpaths
        Dim tp As PowerMILL.Toolpath
        Dim lv3Item As New ListViewItem
        ListView3.Items.Clear()
        ListView1.Items.Clear()
        For Each tp In tps
            lv3Item = ListView3.Items.Add(tp.Tool.Number.Value) 'Add the Toolpath name to the list.
            lv3Item.SubItems.Add(tp.Tool.Name)
            lv3Item.SubItems.Add(tp.Name)

        Next 


        Dim Conflicts = From ListItem In ListView3.Items _
                        Select Number = CType(ListItem, ListViewItem).SubItems(0).Text, _
                        Name = CType(ListItem, ListViewItem).SubItems(1).Text _
                        Distinct _
                        Group By ConflictedGroup = Number _
                        Into DuplicatedNumbers = Group, Count() _
                        Where (Count > 1)

        If Conflicts.Count > 0 Then
            Dim Message As String = "The Following Tool Conflicts Have Occured :-" & vbCrLf
            For Each ConflictedGroup In Conflicts
                Message &= vbCrLf
                For Each DuplicatedName In ConflictedGroup.DuplicatedNumbers
                    Message &= vbTab & "T" & duplicatedName.Number & " : " & DuplicatedName & vbCrLf

                Next
            Next
            MsgBox(Message, MsgBoxStyle.OkCancel, "Conflicting Tools Found!")
        End If
End Sub

The only thing I can see is DuplicatedName should have DuplicatedName.Name on the line where you are &= the message with the text.

I see sortColumn. Do you happen to have a ListViewItemComparer in that form. I have the same variable with a couple of forms I use with listviews. Just curious.

Yes,I've just been through & noticed the DuplicatedName.Name typo,changed it
and no change.
Yes,I sort the same listview columns with this,sometimes this listview control gets loaded with up to 150 tools so it's nice to be able to throw them into numeric order.
I have 2 classes each with an Icomparer for Numeric and String sorting,you think these could be throwing a spanner in the works?

The Icomparer should have no affect. Just curious.


I really can't explain why your getting the error. I see nothing wrong.

Try commenting out everything above the Dim Conflicts and adding a temp for loop to add a few items to listview3 and see if the same error happens.

This question has already been answered. Start a new discussion instead.