if (oAppt.Body.StartsWith("Dette er en automatisk genereret")) { System.Console.WriteLine("Sletter aftalen for med overskriften : " + oAppt.Subject + " - Dato : " + oAppt.Start); String T = Convert.ToString(oAppt.Subject); oAppt.Delete(); }
Den kører et antal aftaler igennem, men så pludselig fejler den med beskeden : "Array index out of bounds."
Hvis jeg f.eks. har 332 objekter som opfylder kravene i mit outlook, så stopper den når den har slettet 152 af aftalerne. Nr. 153 siger den denne fejl på!
Hvis jeg så fortsætter, så kører den lidt igen og stopper så igen!
Det kan jeg så blive ved med indtil den har slettet dem alle... Og hvis jeg bare gider trykker "Continue" mange gange nok, så får den slettet dem alle!
I lang tid har samarbejdsbranchen fokuseret på at forbedre enhedsfunktioner – bedre kameraer, klarere lyd og smartere software. Men den virkelige forvandling handler ikke om funktioner.
tror vi skal se noget andet kode.. du har jo også en variabel i.. men prøv dette
foreach(Outlook.AppointmentItem oAppt in oItems) { try {
if (oAppt.Body.StartsWith("Dette er en automatisk genereret")) { System.Console.WriteLine("Sletter aftalen for med overskriften : " + oAppt.Subject + " - Dato : " + oAppt.Start); String T = Convert.ToString(oAppt.Subject); oAppt.Delete(); }
Jeg tror det er fordi du itererer igennem en liste samtidig med at du fjerner elementer fra listen.
Du initialiserer jo formodentlig variablen "I" til antallet af aftaler. Det antal vil imidlertid blive mindre og mindre efterhånden som du fjerner elementer, med det resultat at du til sidst forsøger at læse ud over enden af listen.
Jeg er i øvrigt også rimeligt sikker på, at den fremgangsmåde du har valgt vil betyde, at du springer elementer over, som altså slet ikke bliver checket.
måske kunne du prøve at sige: for (int J = 1; J <= oItems.Count; J++) i stedet for: for (int J = 1; J <= I; J++) Så tror jeg din exception forsvinder, men det løser ikke problemet med at du springer elementer over.
bitmatic, jeg kan godt se din logik. Jeg prøver lige det du siger.
Hvad angår at jeg springer objekter over, så tror jeg nok at jeg har fat i dem alle... For hvis jeg samtidig åbner mit outlook, søger efter kalender aftaler med teksten "Dette er en automatisk genereret"... Så kan jeg følge resultatet løbende, hvor jeg kan se at den til sidst kommer ned på 0.
Nej, den der med string T = osv.... Det var bare fordi jeg lige havde et break point, og så gerne lige ville se hvad overskriften var på hver kalenderaftale. Glemte jeg lige at få slettet igen inden jeg copy pasted mine kode over! Sorry....
string[] liste = new string[3]; list[0] = "Hejsa"; list[1] = "Det her er"; list[2] = "Godt";
foreach(string tekst in liste) { Console.WriteLine(tekst); }
dvs. den første string i løkken her angiver hvilken type objekter jeg vil løbe igennem. tekst er bare den variabel de skal gemmes i. liste er den struktur jeg vil løbe igennem. foreach(string tekst in liste)
bitmatic's løsning gør det samme så den burde virke.
Objekter skal kunne returnere en enumerator for at virke med foreach. Det er der noget der tyder på at Outlook.AppointmentItem ikke kan. Derfor vikrer det ikke med foreach.
Hmmm.... Kunne ikke lige se mig ud af det du skrev kalp med det eksempel.
Men det er nu også lige meget! Jeg fik det til at virke ved at bruge oitems.count i stedet for I, som du skrev bitmatic.
Altså : for (int J = 1; J <= oItems.Count; J++)
Det er jo mega logisk når man lige tænker sig om... Og den får slettet alle entries. Jeg kan i hvert fald ikke finde nogle tilbage i mit outlook bagefter.
Så hvis i begge smider et svar, så får i points :-)
Jeg har ikke forsøgt at bruge det. ville lige prøve det bitmatic skrev først. Og det fungerede for mig, så var der jo ingen grund til at prøve noget andet...
Nå, jeg fandt jo ud af at bitmatic havde ret i at den ikke sletter alle elementer alligevel!
kalp, kan du ikke give et eksempel på hvordan du ville opstille en regl for hvilke elementer der skal løbes igennem, for at fjerne den fejl jeg skrev tidligere...
Jeg forstår nogenlunde hvad du mener i dit eksempel, men formår åbenbart ikke at få det omsat til noget brugbart i mit projekt.
foreach (Outlook.AppointmentItem oAppt in oItems) { try { if (oAppt.Body != null) { if (oAppt.Body.StartsWith("Dette er en automatisk genereret")) { System.Console.WriteLine(Convert.ToString(J) + " ud af " + Convert.ToString(oItems.Count) + " - Sletter aftalen for med overskriften : " + oAppt.Subject + " - Dato : " + oAppt.Start);
før vi kigger på mit så tror jeg måske en forståelse af hvad det er der sker måske kan afklare problemet.. der er ting i din løkke som jeg undre mig over..
ja måske men det det er svært at sige fordi jeg ikke kender til resten af systemet... jeg ville nok prøve at lave en foreach på Outlook og ikke Outlook.AppointmentItem
men det ville kræve nogle ændringer selvfølgelig i koden flere steder..
man kan sagtens få det andet til at virke, men det kræver at du er lidt detaljeret:) så man har en chance.. problemet er nemlig ikke stort, men det er bare et manglende overblik fra min side af der gør at jeg ikke kan komme med løsningen.
den slettede ikke nogle elementer sagde du ? var der noget specielt ved disse f.eks?
og jeg kunne stadig godt tænke mig at se hvor variablen "i" som var med i dit første kom fra.. evt. hvordan du udfyler oItems med værdier..
Jeg går lige lidt tilbage i ændringerne på min kode. Koden er ikke så stor og indeholder ingen følsomme data. Jeg uploader den lige på min hjemmeside, så kan du jo se hele koden hvis det var.
OK?
Du vil nok ikke kunne køre koden, da den laver et SQL kald og hente nogle medarbejder data ud fra vores gamle AS/400 system. Jeg laver et udtræk hver nat fra AS/400 til en SQL server, og henter så medarbejder data fra denne SQL Server. Her har jeg bare ændret password i min kode pt, så der er ingen følsomme ting i den overhovedet.
Du falder sikkert over nogle andre ting, jeg kunne gøre noget mere smart. For mig gælder det dog pt. bare om at få dette til at virke. Så kan jeg fintrimme koden bagefter!
Den kigger på de outlook profiler der er oprettet på ens PC, og bruger dem til at oprette forbindelse til folks outlook kalendere.
Systemet skal bruges til at oprette medarbejderes fødselsdatoer og jubilæer i forskellige outlook kalendere.
Når en medarbdejder ansættes oprettes han i AS/400 systemet, som er vores løn styringssystem bl.a.
Et døgn efter er medarbejderen så med i SQL udtrækket jeg laver hver nat, og hans fødselsdag osv oprettes så automatisk i outlook...
Det som altså er galt med den kode der ligger der pt, er at den ikke sletter alle aftaler.
Den fejler ikke og sletter en del kalenderaftaler. Når den er nået en del af vejen, så stopper den dog med at slette og begynder i stedet at oprette aftaler igen, ud fra resultaterne i det SQL udtræk den laver. Oprettelserne fungerer perfekt!
Så eneste fejl i den kode, der ligger der pt, er at den ikke sletter specielt mange aftaler før den begynder at oprette. Det betyder så at mange aftaler kommer til at ligge 2 gange, og næste gang 3 gange osv osv osv...
Det skal nok lige siges, at kommentarerne i koden ikke er tiltænkt dig kalp. Mere hvis en anden skal rette noget når jeg engang om 100 år er død og borte eller forlader virksomheden, som jeg skal lave dette for...
jeg bliver nød til at se på det i morgen med mit VS2005, men men men.. måske virker det allerede sådan her hvis du er heldig.. ellers må jeg løse det i morgen.. men den her må være tæt på!
Outlook.AppointmentItem oAppt = null;
foreach (object data in oItems) { try { oAppt = data as Outlook.AppointmentItem; if(oAppt != null) {
if (oAppt.Body.StartsWith("Dette er en automatisk genereret")) { System.Console.WriteLine("Sletter aftalen for med overskriften : " + oAppt.Subject + " - Dato : " + oAppt.Start); String T = Convert.ToString(oAppt.Subject); oAppt.Delete(); }
Hvis du har problemer med at den ikke fjerner dem alle, tror jeg at det hænger sammen med det jeg skrev tidligere om at du springer elementer over, fordi du fjerner elementer imens du itererer igennem listen. Det kommer lidt an på hvorledes iteratoren er implementeret helt nede i maven på containeren, men det kunne være det der er problemet.
Et oversimplificeret eksempel (pseudokode):
Lad os lege at jeg står med et array af karakterer der ser sådan her ud: X = {A,B,C,D,E}
Jeg vil gerne fjerne alle konsonanterne, så jeg laver noget lignende af: for(int i=0; i<X.Count; ++i) { if (X[i].IsConsonant) X[i].RemoveFromArray(); }
Første gang løkken kører kigger koden på X[0] som er et A. Koden gør ingenting. Anden gang løkken kører kigger koden på X[1] som er et B. Koden fjerner altså B'et. Tredje gang løkken kører kigger koden på X[2] som er et D !!! (fordi B'et jo er fjernet, så arrayet ser nu sådan her ud {A,C,D,E}. Koden har altså sprunget C'et over.
Det er da en teori :-)
Men om den er rigtig afhænger helt af hvordan din container er skruet sammen.
Til kalp : Den kommer stadig med samme fejl omkring GetEnumerator efter jeg har rettet til det kode eksempel du skriver sidst.
Til Bitmatic. Du har ret, mit problem er som du beskriver. Men hvordan kan man løse det? Hvordan får man den til at løbe ALLE elemente igennem når listen bliver kortere og kortere?
Jeg kunne jo løbe listen igennem 500 gange. Det ville nok virke for mig pt. men det er jo ingen holdbar løsning.
Fandt ud af at har man Office 2003 så er der en GetEnumerator man kan bruge. Men jeg har kun Office XP installeret, og den har ikke nogen!
Jeg har nu installeret Office 2003, men den har så andre "skavanker"... Så jeg tænkte på en anden løsning.
Kunne man ikke bare lave et nyt array i sin kode. Og når jeg løber alle kalenderaftaler igennem, så i stedet for at slette dem der opfylder kravet om bestemt indhold, så bare tilføje dem til det nye array. Hver kalenderaftale har et ID, så jeg kunne jo bare tilføje dette ID til det nye array.
Og når man så er færdig med at løbe dem alle igennem, så tage alle objekter i det nye array og for hvert af disse slette den kalenderaftale der har det pågældende ID.
Hvis ikke oItems er read-only kan du måske bare løbe den igennem, kopiere de aftaler du vil beholde over i et nyt array, og til sidst sætte oItems lig med det nye array.
En alternativ løsning er at dekrementere tælleren hver gang du har fjernet et element, for at kompensere for at arrayet er ændret....
if (oAppt.Body.StartsWith("Dette er en automatisk genereret")) { System.Console.WriteLine("Sletter aftalen for med overskriften : " + oAppt.Subject + " - Dato : " + oAppt.Start);
Men så er du nok lige nødt til at teste at det virker omkring det første og sidste element i array'et. Det tror jeg nu nok det gør. Men så er du ved at være ude i en løsning hvor du itererer igennem et array, imens du ændrer både array'et og iteratoren.... Det er ikke nødvendigvis særligt læsbart når du kommer tilbage til koden om 1 år :-)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.