Results 1 to 10 of 10

Thread: foutafhandeling bij uitlezen bookmarks in Word document

  1. #1

    foutafhandeling bij uitlezen bookmarks in Word document

    Hallo,

    In mijn applicatie lees ik de waardes van een aantal bookmarks uit, uit een word document middels onderstaande code
    Code:
    function TMSWord.get_bookmarktext(Name: string; Option: TBM_Option): string;
    var
     vwhat: olevariant;
     extend: olevariant;
     bookmark: olevariant;
    begin
     Result:='';
    
     vWhat := wdGoToBookmark;
     extend := wdextend;
     bookmark := Name;
    
     try
      ClipBoard.Clear;
     except
    
     end;
    
    
     try
      WordApp.selection.GoTo(vwhat, emptyParam, emptyParam, Bookmark);
     except
      Result:='Bookmark not Found';
      exit;
     end;
    
     case option of
      bm_Graph:
      begin
       WordApp.Selection.MoveRight(wdSentence,1,Extend);
       WordApp.Selection.Copy;
       delay(100);
       Result:='';
      end;
    
      else
      begin
       WordApp.Selection.MoveRight(wdSentence,1,Extend);
       WordApp.Selection.Copy;
       delay(100);
       Result:=trim(Clipboard.AsText);
      end;
     end;
    
    
    
    end;
    Echter ik krijg regelmatig (wel random) een foutmelding (Cannot open clipboard: toegang geweigerd) op de functie:
    ClipBoard.Clear;
    In debug mode kom ik in de except uit en loopt mijn programma gewoon verder.
    Echter wanneer ik de gecompileerde versie uitvoer krijg ik een foutmelding "Cannot open clipboard" en blijft mijn programma hangen.

    Hoe kan ik er voor zorgen dat de foutmelding op een juiste manier wordt afgehandeld of dat deze niet meer optreed.

  2. #2
    Die foutmelding zal niet komen van die regel waar die try..except omheen staat. Wellicht ontstaat het bij het uitlezen van `Clipboard.AsText`. In het kort komt het erop neer dat andere applicaties ook weleens wat met het clipboard doen. Zodra jij iets wijzigt (of als je .Clear aanroept), dan worden andere applicaties daarvan op de hoogte gesteld, en die kunnen dan gaan lezen wat er veranderd is. Dat kan maar met één tegelijk, dus kan het Clipboard gelockt zijn voor je volgende actie. Het enige wat je kan doen is het een aantal keer proberen todat het lukt.

    Maar nog beter is het om heel het clipboard niet te gebruiken. Een iets betere manier is om de text van de selectie op te vragen

    Delphi Code:
    1. Result := WordApp.Selection.Range.Text;

    Nog beter is het om zelfs niet de selectie te veranderen:

    Delphi Code:
    1. Result := WordApp.ActiveDocument.Bookmarks(Name).Range.Text;

    Als je nog een tandje verder gaat, gebruik je specifiek het document dat je geopend hebt, in plaats van af te gaan op ActiveDocument. WordApp.Selection geeft de selectie van het actieve document weer. Dat is foutgevoelig (de gebruiker kan terwijl een ander document activeren), en traag en storend (de selectie wordt ook actief bijgewerkt op het scherm, als het document zichtbaar is).

    Idealiter zou je een functie hebben die iets doet als:

    Delphi Code:
    1. if MyDocument.Bookmarks.Exists(Name) then
    2.   Result := MyDocument.Bookmarks(Name).Range.Text;

    Dit is overigens even uit het hoofd getikt. Het kan zijn dat je Bookmarks.Items(Name), of Bookmarks[Name] o.i.d. moet gebruiken.
    1+1=b

  3. #3
    Thanks voor de update
    De manier zoals je beschrijft is idd een stuk netter.

    Helaas krijg ik op deze manier niks terug
    Ook niet als ik eerst zelf een waarde invul middels
    WordApp.ActiveDocument.Bookmarks(Name).Range.Text := 'Test';

    Het punt is dat ik werk met een lijst van bookmarks die ingevuld moeten worden, helaas kunnen in deze lijst ook dubbele voorkomen.
    Door nu te kijken of de bookmark al is ingevuld kan ik voorkomen dat de bookmark meerdere keren wordt ingevuld.

    Uiteraard zijn er ook andere oplossingen te bedenken om te voorkomen
    maar het liefst houd ik vast aan mijn huidige opzet.

  4. #4
    Krijg je de exception altijd of alleen maar af en toe?

    Je zou een repeat in kunnen bouwen rond de exception als het af en toe is.
    https://stackoverflow.com/a/4649101/1037511

    Als het altijd is dan zul je eerst moeten kijken wie en waarom het clipboard niet te openen is (of in gebruik is op een andere plaats).

    Waar heb je overigens de Clipboard.Open; en Clipboard.Close; staan? Of zijn die niet nodig bij gebruik van Clipboard.AsText?

  5. #5
    De fout treed random op
    Ik maak geen gebruik van clipboard.open / close
    Maar wellicht kan ik hiermee wel mijn code verbeteren

    Ga nog even wat proberen

  6. #6
    Het kan sowieso ook zijn dat er andere programma's "kijken" naar het clipboard. En als dat op precies hetzelfde tijdstip gebeurd dan kun jij een Access denied krijgen. Dan zou je het dus nog een keer moeten proberen (vandaar die repeat op de exception). Je moet ook even kijken of je misschien clipboard-afvangers in de lucht hebt. Die zou je even uit kunnen schakelen (maar dat werkt bij je gebruikers natuurlijk niet dus altijd aannemen dat toegang tot het clipboard tijdelijk niet mogelijk is).

  7. #7
    Clipboard.Open en Clipboard.Close worden impliciet aangeroepen vanuit AsText en Clear. Maar ze zijn als het ware reference counted. Je kan dus ook het clipboard openen, meerdere acties doen (clear, AsText), en het daarna weer sluiten. Op die manier heb je minder of geen risico dat andere applicaties het clipboard halverwege gaan locken als gevolg van de eerste actie die je doet.

    Die initiële Clipboard.Open kan natuurlijk nog steeds mislukken...
    1+1=b

  8. #8
    W.b. die bladwijzers, daar was iets mee. Je hebt enkele bladwijzers (die geven alleen een positie aan, zijn verder leeg) en blokbladwijzers (die geven een bereik aan, bevatten inhoud). Als je een bladwijzer op de cursorpositie maakt dan krijg je een enkele bladwijzer, en als je een selectie hebt en een bladwijzer maakt, dan is het zo'n blokbladwijzer.

    Als ik me goed herinner (het is ruim 11 jaar geleden dat ik in de sjablonenbusiness zat), werkt het zetten via de range niet op zo'n enkele bladwijzer, maar dat weet ik niet meer precies. Een ander probleem is dat een blokbladwijzers verdwijnt als je de tekst van de range zet. Ik meen dat we daar destijds logica voor hadden om expliciet het type van de bladwijzer te checken, en na het schrijven van de tekst de bladwijzer weer te herstellen.

    Met even zoeken vond ik dit het artikel Insert Text "At" or "In" a Bookmark dat aardig lijkt te beschrijven hoe ik het destijds deed.
    1+1=b

  9. #9
    Oh nee, het ging over het uitlezen. Even terugkijkend naar je code spring je naar een bookmark en selecteer je vervolgens de hele zin, om die te kopieren. Ik neem dus aan dat de bookmarks zelf niet de zin bevatten (maar alleen in de zin staan). Ik neem dus aan dat je vanuit de range van de bookmark moet werken om die uit te breiden tot de hele zin.

    Range.Expand(wdSentence) is een mogelijkheid om de range uit te breiden, en wellicht kan je ook nog wat met de collectie Range.Sentences.

    Iets van:

    Delphi Code:
    1. Range := Document.Bookmarks(Naam).Range;
    2. Range.Expand(wdSentence);
    3. Result := Range.Text;

    Sorry dat ik al die ongeteste code dump, maar ik heb geen werkende Word meer.
    1+1=b

  10. #10
    Bedankt voor de heldere uitleg ook voor de link erg interessant
    Heb de clipboard functie nu er uit gehaald.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •