danturn 1 Light Poster

Hey guys,

I've got 2 collections (one datatable and one list of an object)

i need to compare them and get a collection of the matches and a collection of the items that dont match (from both collections)

i've got the matched collection sorted:

var yourNumbers = from DataRow yourNumber in yourNumberList.Rows
                               select new
                               {
                                   type = yourNumber["DDITYPEID"].ToString(),
                                   extension = yourNumber["EXTENSION"].ToString()
                               };

            var myNumbers = from myNumber in myNumberList
                              select new
                              {
                                  type = myNumber.type,
                                  extension = myNumber.number,
                                  key = myNumber.key
                              };

            var matchedNumbers = from vossNumber in vossNumbers
                                 join smartNumber in smartNumbers on vossNumber.extension equals smartNumber.extension
                                 select new
                                 {
                                     smartNumber.type,
                                     smartNumber.extension,
                                     vossNumber.key
                                 };

that works fine, but im struggling with the unmatched.

i've tried this:

var unmatchedNumbers =
                myNumbers.Except(myNumbers.Join(yourNumbers, myNumber => myNumber.extension,
                                                    yourNumber => yourNumber.extension,
                                                    (myNumber, yourNumber) => myNumber));

which returns items that are in the mynumber list only but not items that are only in the yournumber list.

any ideas?

dan

danturn 1 Light Poster

Hey guys,

i'm struggling slightly with my UI for a project.

I have a listview bound to a observablecollection (userList) of users, users has 3 properties (windowsUser,PhoneUserId,PhonePin)

i have an edit button, and update button and three text boxes (TBWindowsUser, TBPhoneUserID, TBPhonePin)

when i click the edit button i want the selected item in the listview to populate the corresponding text boxes then the user can edit the values and click update to apply the changes...

I've almost got this working... but it also updates when you tab between the text boxes i need it to not update until you click the button at the end...

any ideas?

(in case you're wondering im setting the binding programatically at the point when the edit button is clicked because the text boxes can also be used to add a new user which doesnt exist in the list box at all - i've removed that part of the code - If you have any other way of performing this arrangement let me know!)
code here:

wpf:

<StackPanel Name ="MainStack" DataContext="{Binding Source = userList}" Height="348">
        <Grid Height="348">
        <TextBox Height="23" HorizontalAlignment="Left" Margin="24,32,0,0" Name="TBWindowsUser" VerticalAlignment="Top" Width="120" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="24,66,0,0" Name="TBPhoneUserId" VerticalAlignment="Top" Width="56" />
        <PasswordBox Margin="91,66,0,0" x:Name="TBPhonePin" PasswordChar="*" HorizontalAlignment="Left" Width="53" Height="23" VerticalAlignment="Top" />
        <Button Height="23" HorizontalAlignment="Right" Click="BUpdateUser_Click" Margin="0,66,61,0" Name="BUpdate" VerticalAlignment="Top" Width="75">Update User</Button>
        <ListView Margin="24,102,24,39" Name="LVUsers" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Windows User" Width="100" DisplayMemberBinding="{Binding Path=WindowsUser}" />
                    <GridViewColumn Header="Phone User ID" Width="100" DisplayMemberBinding="{Binding Path=PhoneUserId}" />
                </GridView> …
danturn 1 Light Poster

DOH,
i made a typo.

it should have been like this:

where CCM0300.dbo.Device.tkModel= '73' AND 
(CCM0300.dbo.NumPlan.DNOrPattern like '31782455'
OR CCM0300.dbo.NumPlan.DNOrPattern like '30088600'
OR CCM0300.dbo.NumPlan.DNOrPattern like '31706305'
OR CCM0300.dbo.NumPlan.DNOrPattern like '31786805'
OR CCM0300.dbo.NumPlan.DNOrPattern like '31708285')
danturn 1 Light Poster

DOH spelt thread name wrong... should be query!

This is surely simple...

this is the end of my query

where CCM0300.dbo.Device.tkModel= '72' AND 
CCM0300.dbo.NumPlan.DNOrPattern like '31455'
OR CCM0300.dbo.NumPlan.DNOrPattern like '38600'
OR CCM0300.dbo.NumPlan.DNOrPattern like '36305'
OR CCM0300.dbo.NumPlan.DNOrPattern like '36805'
OR CCM0300.dbo.NumPlan.DNOrPattern like '38285'

what this is meant to do is return the records that are type 72 AND contain any of the numbers below.

this seems to work exept that it doesnt return the first record 31455...

i'm guessing this is because it sees CCM0300.dbo.Device.tkModel= '72' AND
CCM0300.dbo.NumPlan.DNOrPattern like '31455' as one statement...

any advice?

Dan

danturn 1 Light Poster

wowza,

That's awesome.

the first option is what i need... the output isnt console, it needs to get banged into a table so i need the heirarchy in place.

I had absolutely no idea how to approach this so thank you very much!

some of the data structures in cisco call manager are quite complicated and the recipient of the data needs it in a completely unrelated format.

yipee!

danturn 1 Light Poster

I may be getting this very wrong as im a total n00b....

but how are you differentiating between first and last name in your string list?

presumably you're just adding to the list the first/last name as one string?

so each list item is like:

"Dan Turner"
"ROT C89"
or whatever?

so you may want to split each string into parts...

foreach (string person in page)
{
       string [] firstLast = person.Split(' ');
   if (firstLast[1].ToLower() == Lname.ToLower())
                {
                    return person;
                }
}

either than or use

if (person.ToLower().indexOf(Lname.ToLower())>-1)
danturn 1 Light Poster

something like this i would imagine:

foreach (string person in page)
{
   if (person.getLastName().ToLower() == Lname.ToLower())
                {
                    return search;
                }
}
danturn 1 Light Poster

Hey Guys...

I've got a bit of a fiddly problem...

I have an XML doc in the following format:

<row>
<DNOrPattern>0444</DNOrPattern>
<HuntList>HL-1104 C Capital</HuntList>
<LineGroup>LG-1000-COREVM1</LineGroup>
<RNAReversionTimeout>4</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>20130</Member>
</row>
<row>
<DNOrPattern>1015</DNOrPattern>
<HuntList>HL-1104 B Ltd</HuntList>
<LineGroup>LG-1000-COREVM1</LineGroup>
<RNAReversionTimeout>4</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>20110</Member>
</row>
<row>
<DNOrPattern>0444</DNOrPattern>
<HuntList>HL-1104 C Capital</HuntList>
<LineGroup>LG-1000-COREVM1</LineGroup>
<RNAReversionTimeout>4</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>20110</Member>
</row>
<row>
<DNOrPattern>0444</DNOrPattern>
<HuntList>HL-1104 C Capital</HuntList>
<LineGroup>LG-1104 C Capital</LineGroup>
<RNAReversionTimeout>12</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>11048624</Member>
</row>
<row>
<DNOrPattern>1015</DNOrPattern>
<HuntList>HL-1104 B Ltd</HuntList>
<LineGroup>LG-1104 B</LineGroup>
<RNAReversionTimeout>4</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>20132</Member>
</row>

I want to read it into some sort of heirarchy along these lines....

DNOrPattern
HuntList
LineGroup
Members

So from the data above i end up with the data in this logical heirarchy i.e. for each DNorPattern i can expand to see the hunt list then expand the huntlist to see the linegroups then expand the linegroups to see the members! (I'm putting this in code to keep the indentation)

DNOrPattern: 1015
	HuntList: HL-1104 B Ltd
			LineGroup: LG-1000-COREVM1
					Member: 20110

			LineGroup: LG-1104 B	
					Member: 20132


DNOrPattern: 0444
	HuntList: HL-1104 C Capital
			LineGroup: LG-1000-COREVM1
					Member: 20110
					Member: 20130

			LineGroup: LG-1104 C Capital
					Member: 11048624

Hope that makes some sense....

I think Linq should be able to do this but i dont know where to begin …

danturn 1 Light Poster

Cool, Thanks for the info! that makes sense

Dan

danturn 1 Light Poster

i got it working doing this sort of thing...

is this what you meant?

STOREUDPs.UDPListStore(builder.ToString());
class STOREUDPs
    {
        private static List<string> UDPList = new List<string>();
        private static string Site;
        private static int Mostlines;
        private static ListBox LBProgress;

        public static void  UDPListStore(string NewUDP)
        {
            UDPList.Add(NewUDP);
        }
        public static List<string> UDPReturner
        {
            get { return UDPList; }
        }
}
danturn 1 Light Poster

Hi Guys,

Is it possible to add a string to a list using a static method or am i really misunderstanding this?

This is what i'm trying...

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace LDAPNOCISCO
{
    class STOREUDPs
    {
        private static List<string> UDPList = new List<string>();

        public static List<string> UDPListStore
        {
            get { return UDPList; }
            set { UDPList.Add(value.ToString()); }
        }
    }
}

then i'm trying to add to UDPList using

builder.Append(DN.ToString() + "," + ModelButton[0] + "," + PhoneButtonTemplate + "," + "All Features"
                    + "," + "," + "," + "," + "," + TheRest.ToString() + "," + noOfLines);
                STOREUDPs.UDPListStore = builder.ToString();

im getting a "cannot convert string to list<string> error though...

any advice?

danturn 1 Light Poster

d'oh...

i was being thick...

i just made a 2nd list and added each new value to the list if it wasn't already there.

in case anyone is curious...

List<string>TempPug= new List<string>();
            TempPug.Add("Starter");
            
            foreach (string PugString in PUGList)
            {
                int foundcount = 1;
                string[] PugDeets = PugString.Split(',');
                if (PugDeets.Count() > PugMemberCount) PugMemberCount = PugDeets.Count();
                PugDeets[7] = PugDeets[6].Replace(" ", "_") + "_" + "Default";
                for (int l = 0;l<=TempPug.Count()-1;l++)
                {
                    if (PugDeets[6] == TempPug[l].ToString())
                    {
                        foundcount++;
                    }
                }
                if (foundcount == 1) TempPug.Add(PugDeets[6].ToString());
                else
                {
                    PugDeets[7] += "-" + foundcount;
                }
                string tempstring = String.Join(",", PugDeets, 0, PugDeets.Count());
                FinalPUGList.Add(tempstring);
            }
danturn 1 Light Poster

Hey guys,

I'm a bit stuck with this issue...

I have a list of comma separated strings.

some of them have a duplicate field in them.

what I want at the end of this process is a List of strings (comma seperated again) with any of the duplicates being marked with a number (ideally 1 for the first duplicate, 2 for the 2nd etc.). The number needs to be appended to a different field to the field i'm checking for duplicates in.

this is what i've tried... it makes each one unique but i only want to append x to the duplicate values

int x = 0;
            foreach (string PugString in PUGList)
            {    
                string[] PugDeets = PugString.Split(',');
                PugDeets[7] = PugDeets[6].Replace(" ","_") +"_"+ "Default";
                foreach (string subPugString in PUGList)
                {
                    string[] SubPugDeets = subPugString.Split(',');

                    if (SubPugDeets[6] == PugDeets[6])
                    {
                        PugDeets[7] += x.ToString();
                        x++;
                    }
                }
                string tempstring = String.Join(",", PugDeets,0,PugDeets.Count());
                
                FinalPUGList.Add(tempstring);
                     
            }

I hope this makes some sort of sense!

I understand why this doesnt do what i want but i cant work out how to get what i'm after!

danturn 1 Light Poster

Sorted. That was exactly what i was trying to do.

If there is any way I can remotely buy you a beer please pm me or something.

You've helped enormously and taught me a lot

Dan

danturn 1 Light Poster

aha, that makes a lot of sense... i've been looking into the Linq stuff today a bit. I think i'm beginning to understand the simple bits but putting it together is a bit of a challenge!

sorry to keep adding to this thread when you've already solved my issues but as it refers to the same code i thought i'd ask you another quicky on here:

This bit of code here:

var udpNames = (from DataRow dr in FinalUsers.Rows
                            select dr[1].ToString())
                            .Distinct();           
            
            var udpGroups = from udpName in udpNames
                            select new
                            {
                                UDPName = udpName,
                                Rows = rows.Where(row => row.UDPName == udpName).OrderBy(row => row.LineNumber),
                            };

is saying Select Column 1 from a row in datatable FinalUsers and make a variable containing that value

then its saying when that variable (from Final Users = the row from the XML matches it return the rest of the values for that row right?

what i've been trying to work out today (i know... i've literally been trying to develop this tiny bit of code for 3 days now!!!!) is how to do the same match... but instead of adding UDPName at this point...

builder.Append(udpGroup.UDPName);

i'm trying to work out how to add the corresponding value in finalusers column [0]

I was hoping you could do something like this:

var udpNames = (from DataRow dr in FinalUsers.Rows
                            select dr[1].ToString(),dr[0].ToString())
                            .Distinct();

then use the combined result to extract [0] later on somehow but i just cant …

danturn 1 Light Poster

aha, ok cool, my first idea was to use a flag somewhere and just inject them on the first run...

i was trying to overcomplicate things by doing something clever and linqy!

again, thanks so much!

danturn 1 Light Poster

Yeah, from the same XML file...

You're right, the relationship is that 1 UDP has 1 Handset Type and Multiple everything else.

i started out trying to get the simple stuff working and figured i could work it out from there, but i have to confess i'm struggling to get my head around it!

Is this handset type coming from the XML file, the datatable, somewhere else? And is the relationship 1 UDPName, 1 handset type, multiple everything else?

danturn 1 Light Poster

one final thing!!!

if there is another field that is in every record but like UDPName it's a duplicate... how do i add that just once at the beginning after UDPName?

i dont need to check it agains the finalusers table, just append it to the UDPName...i figure i would need to add it here (********):

foreach (var udpGroup in udpGroups)
            {
                builder.Append(udpGroup.UDPName+","+********);

but i can't work out how to reference another value in the Rows...

I suspect i need to add to my query here:..

var udpGroups = from udpName in udpNames
                            select new
                            {
                                UDPName = udpName,
                                Rows = rows.Where(row => row.UDPName == udpName).OrderBy(row => row.LineNumber),
                            };

then i can do this:

builder.Append(udpGroup.UDPName+","+udpGroup.PhoneModel);

but i cant work the syntax out...

in case you are curious the field is the handset type of the UDP which owns the speed dials so i dont need to show it multiple times

danturn 1 Light Poster

Wowza....

That's amazing!...

Thanks so much fo your help,

There's no real reason for me to use ArrayLists other than i know how to work with them! i've switched it to the Lists now.

It's amazing (and terrifying!) how much there is there is to learn in dotnet. i'm going to go read up about Linq i think... all of the other programs i've written are similar dataprocessing/mashing scripts so it's probably a useful tool for that sort of thing!

Dan

danturn 1 Light Poster

Hey Ape,

One last question about the Linq stuff...

if i need to tweak my output slightly -

i.e. instead of showing as:

UDPName,Label1,SpeedDialNumber1,Label2,SpeedDialNumber2,Label3,SpeedDialNumber3...

i need to show it as:

UDPName,Label1,Label2,Label3,SpeedDialNumber1,SpeedDial2,SpeedDial3...

soooo.... still merge all the results for matching UDPs to one line but change the order they're added to the string in so that all of the labels show before all of the numbers.

danturn 1 Light Poster

Hey Ape,

Awesome... i worked it out... I even managed to sort out the next step where i needed to cross reference the XML items against a datatable and only add matches to the array... in case you're curious here's the code...

Thanks for all of your help... i think the Linq stuff is going to come in handy as i have a lot more (more complex) processing to do in the next bit!.

I'm thinking i should have just used some sort of relational database to do all this crossreferncing etc. do you know of any free DB products you can embed in a C# program? - i really need this to be a standalone program.

string XMLResp = SoapSend.SoapSender(sAXLRequest);
            XDocument document = XDocument.Parse(XMLResp);
            ArrayList speeddialsarray = new ArrayList();
            var rows = from row in document.Descendants("row")
                       select new
                       {
                           UDPName = row.Element("UDPName").Value,
                           SpeedDialIndex = int.Parse(row.Element("SpeedDialIndex").Value),
                           Label = row.Element("Label").Value,
                           SpeedDialNumber = row.Element("SpeedDialNumber").Value
                       };
            var udpNames = rows.Select(row => row.UDPName).Distinct();
            var udpGroups = from udpName in udpNames
                            select new
                            {
                                UDPName = udpName,
                                Rows = rows.Where(row => row.UDPName == udpName).OrderBy(row => row.SpeedDialIndex)
                            };
            StringBuilder builder = new StringBuilder();
            foreach (var udpGroup in udpGroups)
            {
                foreach (DataRow DRFinal in FinalUsers.Rows)
                {
                    if (udpGroup.UDPName == DRFinal[1].ToString())
                    {
                        builder.Append(DRFinal[0].ToString());
                        foreach (var row in udpGroup.Rows)
                        {
                            builder.Append(string.Format(",{0},{1}", row.Label, row.SpeedDialNumber));
                        }
                        speeddialsarray.Add(builder.ToString());
                        builder.Remove(0, builder.Length);
                    }
                }
            }
danturn 1 Light Poster

im using 2008 pro...

the project is 3.5 and i've added the references...

i think its just cos you loaded in and XML file to an XDocument whereas im starting with the XMl in an XMLDocument variable...

there doesnt seem to be an option in the xdocument.load to import an XMLDocument type so i was a bit stuck without going back and changing my other classes to return something else... i guess i can just return a string then use xdocument.load() to read it in?

Again, thanks for all the help guys!

Dan

What version of Visual Studio/C# are you using?

You need to have access to .NET 3.5

-Establish reference to System.Core (for LINQ)
-Establish reference to System.Xml.Linq (for LINQ to XML)
-add the following using directives:

using System.Linq;
using System.Xml.Linq;
danturn 1 Light Poster

Hey Guys,

Thanks for that....

glad my code made some sense...

while writing it I felt like i was drowning!

Ape...
i couldnt get the linq stuff to work... it had a problem with using "Descendants" i think the issue is that i had the XML in an XMLdocument format whereas you're using XDocument ... i couldnt work out how to transform it to the other one...

danturn 1 Light Poster

cool, i got it working (in an ugly way)...

dv is the dataview i showed you guys...

im sure there is a simpler way to do this...

its to automate something very painful we do in the office (internal use, not for $ gain!)

ArrayList SpeedDialARR = new ArrayList();
            DataTable FinalSpeedDials = new DataTable();
            string SpeedDialTxt="";
            for (int i = 0; i <= dv.Count - 1; i++)
            {
                if (SpeedDialTxt != "")
                {
                    if (SpeedDialTxt.Substring(0, 8) == dv[i].Row[0].ToString())
                    {
                        SpeedDialTxt += dv[i].Row[2].ToString() + "," + dv[i].Row[3].ToString()+",";
                    }
                    else
                    {
                        SpeedDialARR.Add(SpeedDialTxt.Substring(0,SpeedDialTxt.Length-1));
                        SpeedDialTxt = dv[i].Row[0].ToString() + "," + dv[i].Row[2].ToString() + "," + dv[i].Row[3].ToString() + ",";
                    }
                }
                else
                {

                    SpeedDialTxt = dv[i].Row[0].ToString() + "," + dv[i].Row[2].ToString() + "," + dv[i].Row[3].ToString() + ",";
                
                }
            }
            SpeedDialARR.Add(SpeedDialTxt.Substring(0, SpeedDialTxt.Length - 1));
apegram commented: Keep at it! +1
danturn 1 Light Poster

Hey guys,

I've got a dataview (shown below)...

UDP Position Label Number
11042266 1 JXXXXX 9XXXXXXXXXXX
11042266 2 GXXXXX 9XXXXXXXXXXX
11042449 1 RXXXXX 11042458
11042458 1 SXXXXX 9XXXXXXXXXXX
11042458 2 IXXXXX 9XXXXXXXXXXX
11042458 4 AXXXXX 9XXXXXXXXXXX
11042458 5 HXXXXX 9XXXXXXXXXXX
11042458 6 MXXXXX 9XXXXXXXXXXX
11042459 1 IXXXXX 9XXXXXXXXXXX
11042459 2 SXXXXX 9XXXXXXXXXXX


you can see in the first column there is a field called UDP which has duplicates ...

what i need to end up with is a collection... probably an arraylist of comma seperated strings in the format...

UDP,Label,Number

but adds the fields Label and Number from the duplicates onto the string in the order of the position field: -

so the first UDP should show like this:

11042266,JXXXXXX,9XXXXXXXXXXX,GXXXXX,9XXXXXXXXXXX

the 2nd should be:
11042449,RXXXXXX,11042458

the 3rd should be:
11042458,SXXXXX,9XXXXXXXXXXX,IXXXXX,9XXXXXXXXXXX,AXXXXXX,9XXXXXXXXXXX,HXXXXXX,9XXXXXXXXXXX,MXXXXXX,9XXXXXXXXXXX

the 4th:
11042159,IXXXXXX,9XXXXXXXXXXX,SXXXXXX,9XXXXXXXXXXX

Hope this makes sense..

i've been trying do do it using loops but am running into difficulty...

Any advice greatly appreciated!

danturn 1 Light Poster

Hey Apegram, that looks pretty simple...

im having some issues with references...

i've moved my program to 3.5 as i believe it needs to be to use Linq...

i've added system.core as a reference and now "Using System.linq" is ok...

but using System.xml.linq isnt working...

"The type or namespace name 'Linq' does not exist in the namespace 'System.xml' (are you missing an assembly reference?)"

danturn 1 Light Poster

Hey Guys,

Quick n00b question...

i have the following XML:

<row>
<UDPName>10014535-Test</UDPName>
<SpeedDialIndex>2</SpeedDialIndex>
<Label>mobile</Label>
<SpeedDialNumber>907********</SpeedDialNumber>
</row>
−
<row>
<UDPName>10014535-Test</UDPName>
<SpeedDialIndex>1</SpeedDialIndex>
<Label>talking clock</Label>
<SpeedDialNumber>9123</SpeedDialNumber>
</row>
-
<row>
<UDPName>10014573-Test</UDPName>
<SpeedDialIndex>1</SpeedDialIndex>
<Label>Work</Label>
<SpeedDialNumber>90203********</SpeedDialNumber>
</row>

(this is a cut down version of the XML.. there would be several hundred rows in the actual xml)

what i need to do is combine these xml bits into a comma seperated string like this:

10014535-Test,1,talking clock,9123,2,mobile,907********
10014573-Test,1,Work,90203*******

i.e. strip out all the tags, and combine any 2 elements with the same <UDPName> value... so that they're on one line with the UDPName showing once at the beginning.

whats the best way to approach this?

Dan