Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: bookmarkit dokumentissa (VB6) (VBA)

Sivun loppuun

pongo [10.03.2006 11:48:59]

#

Wordin VBA:ssa dokumentin bookmarkit saadaan valittua ensimmäisten merkkien perusteella, esim. dokumentissa on n määrä "bas"-alkuisia bookmarkeja, joissa on enemmän kuin 3 merkkiä. Nämä saadaan valittua 3 ensimmäisen merkin perusteella, olen tehnyt näin:

For Each Bookmark In ActiveDocument.Bookmarks

If optASME.Value = False And Left(Bookmark, 5) = "bas_A" Then
  Bookmark.Select
  Selection.Delete
End If
Next

Visual Basicissa tämä ei toimi näin. Koodi hakee dokumentin ensin auki ja sen jälkeen pitäisi kaikki esim. "bas"-alkuiset bookmarkit poistaa tai eräässä tapauksessa näihin bookmarkeihin pitäisi lisätä vakioteksti, joka on syötetty textboxiin.

Olisko kenelläkään vinkkiä?

BadSource [10.03.2006 12:51:19]

#

Lisää projektiisi referenssi "Microsoft Word X Object Library" (Project->References...), jossa x viittaa Word-versioosi. Seuraavaa koodia soveltamalla saat tuon tehtäväsi tehtyä.

Dim wrdDoc As Word.Document
Dim bkmrk As Word.Bookmark
Dim polku As String

'Määritetään polku haluamaamme tiedostoon
polku = "C:\Documents and Settings\xxx\My Documents\Being an Evil Overlord.doc"
'Aktivoidaan tiedosto käyttöömme. Tiedostoa ei tuoda näkyviin, ellemme erikseen sitä halua.
Set wrdDoc = GetObject(polku)
'Käydään läpi tiedoston bookmarkit ja tulostetaan ne Immediate-ikkunaan.
For Each bkmrk In wrdDoc.Bookmarks
    Debug.Print bkmrk.Name
Next bkmrk
'Suljetaan kaikki käyttämämme viittaukset viemästä tietokoneen muistia
Set bkmrk = Nothing
'Jos tiedostoon olisi tehty muutoksia, niin niiden tallentamisesta tulisi ilmoitus sulkemisen yhteydessä.
'Estetään ilmoitus kertomalla tiedostolle, että muutokset on jo tallennettu.
wrdDoc.Saved = True
wrdDoc.Close             'Suljetaan tiedosto
Set wrdDoc = Nothing     'Vapautetaan tiedoston varaama muisti

pongo [10.03.2006 15:07:13]

#

Kiitos. Sain immediate -ikkunaan bookmarkit, mutta miten saan määritettyä eri bookmarkeille uuden arvon (textbox.text) -kentistä? Näitä on useampi erilainen. Haluaisin samanalkuiset bookmarkit esim. 3 merkin tarkkuudella vaihdettua ilman, että luettelen jokaisen bookmarkin kokonaisuudessaan, koodista tulee tosi pitkä.

En muuten keksi, miten Immediate-ikkunaa voi hyödyntää..?

BadSource [13.03.2006 07:35:25]

#

Jos ehto on aina sama, niin voit käyttää Select Case-rakennetta korvaamaan useat If-tarkastelut.

Dim Montako As Long
'Select Case on ehtorakenne, jolla voidaan helposti määritellä eri vaihtoehdoille eri tapahtumat
'LCase = käsitellään merkkijonoa pienin kirjaimin
'Left = luetaan vasemmasta reunasta haluttu määrä merkkejä
'Kaksoispisteellä kootaan yhdelle riville useampia koodirivejä.
Select Case LCase(Left(bkmrk.Name, 3))
    'jos kirjanmerkin alku on bas kirjainten koosta riippumatta, niin suoritetaan tämä rivi
    'koska kirjanmerkin nimen pitää olla yksilöllinen, niin lisätään niiden perään yksilöivä numero Montako
    Case "bas": Montako = Montako + 1: bkmrk.name = "foo_" & Montako
    'jos alku on sab, niin suoritetaan tämä rivi
    Case "sab": Montako = Montako + 1: bkmrk.name = textbox.text & Montako
    'muissa tapauksissa kirjanmerkki poistetaan
    Case Else: bkmrk.Delete
End Select

* Immediate-ikkunaa käytetään koodin testauksessa.
* Debug.Print-rakenne tulostaa kyseiseen ikkunaan.
* Muutujien/koodin pätkän arvoa voi testata ?:llä koodin alussa. Eli edellisen koodini Select Case -ehdon arvon LCase(Left(bkmrk.Name, 3)) voi tarkistaa kirjoittamalla

?LCase(Left(bkmrk.Name, 3))

Immediate ikkunaan.
* Kyseisessä ikkunassa voi myös muuttaa muuttujien arvoa ihan vain sijoituslauseella kesken koodin suorituksen, kun suoritus on pysähtynyt jollekkin koodiriville, jonka aikana muuttuja on käytössä.

pongo [13.03.2006 09:48:07]

#

Koodissa bkmrk.name hälyttää .Name -osuutta: "Can't assign to read-only property (Compile error), mikä meni pieleen?
Tässä koodin rivi, jossa häly ensimmäisen kerran (myös seuraava vastaava hälyttää jos ensimmäisen poistaa):

Case "bas": Montako = Montako + 1: bkmrk.name = "foo_" & Montako

BadSource [13.03.2006 13:13:29]

#

Name on tosiaankin vain ReadOnly-arvo, eli sitä ei pysty muuttamaan. Tuon voi kokeilla kiertää Copy-komennolla, jolla tehdään kyseisestä kirjanmerkistä kopio uudella nimellä. Tällöin vanha kirjanmerkki pitää poistaa Delete-komennolla, sillä muuten sekin jäisi vielä jäljelle.

If bkmrk.Name="foo" Then
    bkmrk.Copy "bar"
    bkmrk.Delete
End If

Huomaa, että muutokset pitää muistaa tallentaa, eli poistaa komento

wrdDoc.Saved = True

ja muuttaa sulkemiskomento muotoon

wrdDoc.Application.Quit True

jossa tuo True-määre tarkoittaa muutosten tallentamista. Jostain syystä testeissäni tuo tallennus ei kuitenkaan tapahtunut joka kerta.

pongo [22.03.2006 17:34:02]

#

Sain bookmarkit toimimaan tekemällä aliohjelman:

Sub ChangeBookmarks(bm As String, Value As String)
    Dim i As Integer
    Dim r As Integer
    On Error GoTo virhe
    For i = 1 To 20
        Call msWord.activedocument.Bookmarks(bm & i).Select
        Call msWord.selection.typetext(Value)
    Next
loppu:
    Exit Sub
virhe:
    Resume loppu
End Sub

Tämä aliohjelma kutsutaan ohjelman sisällä:

Call ChangeBookmarks("pv_", txtProduct.Text)
Call ChangeBookmarks("cust_", txtCustName.Text)
Call ChangeBookmarks("add1_", txtAddress1.Text)
Call ChangeBookmarks("add2_", txtAddress2.Text)

Kiitos BadSource neuvoista (vaikka en osannutkaan ohjeidesi avulla viemään koodia loppuun), olet aika guru Visual Basic 6 käsittelyssä! Sain avullasi toisen ongelman ratkaistuksi (.pdf-tiedoston tulostaminen). Toivottavasti jaksat neuvoa meitä aloittelijoita jatkossakin.

BadSource [23.03.2006 08:32:06]

#

Jos olet itse saanut ratkaistua ongelmasi, niin sehän on parempi, kuin kopioida valmista koodia sellaisenaan, sillä oman ratkaisun muistaa paremmin jatkossakin. =)

pongo [23.03.2006 14:34:57]

#

He-ehei! En saanut itse ratkaistua ongelmaa, sain konsulttiapua isolla rahalla...

Mutta siinä olet oikeassa, että kun on saanut toimivaa koodia, voi sitä tutkia ja jopa välillä ymmärtää, miksi niin tehtiin. Pikkuhiljaa alkaa tajuta edes jotain.

;-)


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta