1

Konu: Word Dosyasına Bilgi Yazmak

Mevcut olan bir .doc dosyam var. 4 sayfadan oluşuyor. Bu sayfalardaki boşluklara bilgi yazmak istiyorum. İstediğim sayfanın satır ve sutununa nasıl bilgi yazabilirim?

2

Re: Word Dosyasına Bilgi Yazmak

Biraz muglak bir soru olmus. Istedigim sayfa ve satir darken sayfa ve satir nolari biliyor musunuz? Biliyorsaniz, Selection.Move() ile gider yazarsiniz.

Bilmiyorsaniz, onu bulmak icin bir kriter kullaniyor olmaniz lazim.

Isin kolayi, eger dokuman uzerinde sizin kontrolunuz var ise Bookmark ya da DocumentVariable kullanmak. O zaman dogrudan Bookmark'a gider yazarsiniz, ya da DocumentVariable degerini kurarsiniz. Ornek:

Visual Fox Pro
#include wdconstants.h

#Define NL Chr(13)+Chr(10)
*** set the LOCALEID to English
nlLocaleId=Sys(3004)        && Save local id
=Sys(3006,1033)                && We will be sending instructions in English
 
Use employee        && test table
oWordDocument=Createobject("word.application")    && Create word object
With oWordDocument
  .Documents.Add && Create a new doc
  .Visible = .T.
  .Activate
  Scan
    .Selection.TypeText('Employee Info Start.'+NL)
    .Selection.TypeText(Transform(emp_id)+NL+First_Name-(' '+Last_Name)+NL)
    .Selection.Collapse(wdCollapseEnd)
    lnRangeStart = .Selection.Range.End && set range for notes text and bookmark
    .Selection.TypeText(Nvl(notes,'')+NL+NL)
    lnRangeEnd   = .Selection.Range.End
    .Activedocument.Bookmarks.Add('b'+Padl(Recno(),2,'0'),.Activedocument.Range(lnRangeStart,lnRangeEnd))
  Endscan
 
  firstBmkName = .Activedocument.Bookmarks(1).Name
  .Activedocument.Bookmarks(1).Select
  Messagebox('first bookmark selected',4096,'',3000)
 
  .Selection.Collapse(wdCollapseEnd)
  .Selection.Expand( wdParagraph )
 
  Messagebox('Deleting para after first bookmark',4096,'',3000)
  .Selection.Delete
  .Selection.TypeText( 'Para deleted' + NL )
 
  If .Activedocument.Bookmarks.Exists(firstBmkName)
    .Activedocument.Bookmarks(firstBmkName).Select
    .Selection.Font.Color = 0xFF
  Endif
Endwith
 
**** Set the LocaleId to the previous value
=Sys(3006,Val(nlLocaleId))

3

Re: Word Dosyasına Bilgi Yazmak

Çetin bey haklısınız.
Sorumu biraz açarak tekrarlıyorum

2 sayfadan oluşan Belge.doc adında bir dosyam var.

1. sayfanın 12.satırının 25 karakterinden veya sütunundan başlamak üzere "Adı" yazılsın.
2.sayfanın 5.satırının 50.kaarekterinden veya sütunundan başlamak üzere "Soyadı" yazılsın.

Bu iki olayı gerçekleştiren bir kod yazabilir misiniz?

4

Re: Word Dosyasına Bilgi Yazmak

Visual Fox Pro
#include wdconstants.h

Local oWord as "word.application"
oWord=Createobject("word.application")    && Create word object
 
With oWord
  .Documents.Open("d:\Temp\GoToTest.docx")
  .Visible = .T.
  .Activate
 
  .Selection.GoTo(wdGoToPage, wdGoToNext, ,"1")
  .Selection.MoveDown(wdLine, 12-1)
  .Selection.MoveRight(wdCharacter, 25-1)
  .Selection.TypeText("Adi")
 
  .Selection.GoTo(wdGoToPage, wdGoToNext, ,"2")
  .Selection.MoveDown(wdLine, 5-1)
  .Selection.MoveRight(wdCharacter, 50-1)
  .Selection.TypeText("Soyadi")
endwith

Ama daha once soyledigim gibi bookmark ya da variable kullanmak daha iyi. Boyle karakterle filan, birisi en ufak degisiklik yaptiginda kayar.

5

Re: Word Dosyasına Bilgi Yazmak

Word dosyası sabit. Bir sözleşme dosyası. Standart maddeler.

6 Son düzenleyen, cetinbasoz (23.10.2014 19:43:00)

Re: Word Dosyasına Bilgi Yazmak

O zaman icinde bookmark kullanmak daha kolay. Bir orneginde istediginiz yerlere bookmark koyup template olarak saklayin. Sonra yenii dokumani o template bazli acip bookmarka gidip istediginiz yazarsiniz:)

Visual Fox Pro
#include "wdcons.h"

Local oWord as "Word.Application"
oWord = CREATEOBJECT("Word.Application")
With oWord
  .visible = .t.
  .Documents.Add("c:\templates\mytemplate.dotx")
  With .ActiveDocument
    lcBookmark1 = "Adi"
    lcBookmark2 = "Soyadi"
      If .Bookmarks.Exists(m.lcBookmark1)
          .Range(.Bookmarks(m.lcBookmarkName1).Range.Start, .Bookmarks(m.lcBookmarkName1).Range.End).TypeText("Adi")
      endif
      If .Bookmarks.Exists(m.lcBookmark2)
          .Range(.Bookmarks(m.lcBookmarkName2).Range.Start, .Bookmarks(m.lcBookmarkName2).Range.End).TypeText("Soyadi")
      endif
  Endwith
EndWith

Bu daha saglam bir yol.

7

Re: Word Dosyasına Bilgi Yazmak

"wdcons.h" dosyasını bulamadım. Nereden indirebilirim?

8

Re: Word Dosyasına Bilgi Yazmak

Çetin Bey,

http://www.denbil.com/Sozlesme.doc dosya burada.

1.sayfadaki adı soyadı karşısına
ve
2. sayfanın sağ alt kısımdaki personel bölümüne aynı isim yazılacak.

Ben maalesef başarılı olamadım.

9

Re: Word Dosyasına Bilgi Yazmak

Once wdconstants.h yi anlatayim. Bunun icin bir sey indirmenize gerek yok. Kendiniz olusturabilirsiniz.

1) Command windowda:
Modify Command wdconstants.h[enter]
ile yeni bir kod penceresin acin. Kenarda dursun.

2) Toolbardan ya da menuden Tools\Object Browser i acin.
3) Object Browser'da en soldaki ikonu clickleyin, COM tabindaki listede icinde Word geceni arayin (adi makineye kurulmus versiyonlara gore degisebiliyor:

Microsoft Word ...
Microsoft Office Word ...
Microsoft.Office.Interop.Word 12.0 ...

gibi. Bulunca secip kapatin. Ilk pencereye "Word" gelmis olmasi lazim.

4) Word nodunu genisletin. "Constants" goreceksiniz. Onu daha once actiginiz kod penceresine surukleyip birakin (surukleme ilk denemede calismayabiliyor). Oraya bir suru #DEFINE yazildigini goreceksiniz. Saklayip kapatin. Artik elinizde wdcontants.h var.

10 Son düzenleyen, cetinbasoz (24.10.2014 09:53:03)

Re: Word Dosyasına Bilgi Yazmak

Not: Burada wdconstants.h gerekmiyor. #DEFINE'lari dogrudan icine ekledim.

Sozlesme.doc'u gorup ne istediginizi daha iyi anlayinca, sanirim bookmark ya da variable yerine (aslinda o da variable) Mail MergeField kullanmak daha iyi diye dusundum.

Once sizin .doc dosyasini actim ve dediginiz her iki yere de:
Insert\Field\MergeField dedim ve field adini AdiSoyadi yaptim. (Insert altinda Quick Parts\Field). Sonra da dosyayi template dosyasi olarak sakladim (doc word 97-2003 dosyasiydi, word 97-2003 template olarak Sozlesme.dot diye sakladim). Template dosyasinin kopyasini asagidaki adresten alabilirsiniz:

http://www.medikosoft.com/cetin/Sozlesme.dot

Sozlesme.dot dosyasi bende d:\temp\SerafettinMentes adli bir dizinde. Asagida ornek olarak bir dizi AdSoyad icin Sozlesmeler.doc adinda dosya olusturan kod var. Kod template dosyayi aciyor, tablodaki her kayit icin yeni bir "section" olacak sekilde Sozlesmeler.doc dosyasini yaratiyor. Arada cursor ve copy to kullandigim icin de, isim bitince ornek tablo siliniyor. Hali hazirda olan bir tablodan  gelecektir buyuk ihtimalle, o zaman silmeden biraz ayarla onu kullanirsiniz (ya da cursor'a select edip bu sekilde silerek kullanirsiniz, nasil isterseniz). Bir de, wdSendToDocument yerine wdSendToPrinter gibi secenekler ile dogrudan printer'a gonderebilirsiniz, onu yaparsaniz, Quit demeden once BackgroundPrintStatus kontrolu yapin, yazim bitti mi diye.

Visual Fox Pro
Local lcTemplate, lcSaveAs, lcDataSource

 
lcTemplate = "D:\temp\SerafettinMentes\Sozlesme.dot"
lcSaveAs = "D:\temp\SerafettinMentes\Sozlesmeler.doc"
lcDataSource = Forcepath(Sys(2015)+'.dbf', Sys(2023))
 
Create Cursor sozlesmeler (SozlesmeID i Autoinc Nextvalue 1, AdiSoyadi v(100))
Insert Into sozlesmeler (AdiSoyadi) Values ('Serafettin Mentes')
Insert Into sozlesmeler (AdiSoyadi) Values ('Cetin Basoz')
Insert Into sozlesmeler (AdiSoyadi) Values ('Mehmet En')
Insert Into sozlesmeler (AdiSoyadi) Values ('Ali Buyuk')
Insert Into sozlesmeler (AdiSoyadi) Values ('Mustafa Sari')
Insert Into sozlesmeler (AdiSoyadi) Values ('Huseyin Lacivert')
Copy To (m.lcDataSource)
 
MergeToDoc(m.lcDataSource, m.lcTemplate, m.lcSaveAs)
 
** Erase Temp table
Erase (m.lcDataSource)
 
Procedure MergeToDoc
    Lparameters tcDataSource, tcTemplate, tcSaveAs
    Wait Window Nowait "Creating Word Document.Please wait..."
 
    #Define wdOpenFormatAuto    0
    #Define wdSendToNewDocument    0
    #Define wdSendToPrinter    1
    #Define wdSendToEmail    2
    #Define wdSendToFax    3
 
    #Define wdAlertsNone    0
    #Define wdDoNotSaveChanges 0
 
    #DEFINE wdFormatDocument97    0   
 
    Local lcConnection, lcSource, lcSQLStatement, loDoc
    m.lcSource = Forcepath('myDummy.udl',Sys(2023))
    If !File(m.lcSource)
        Strtofile('',m.lcSource)
    Endif
 
    lcConnection = 'Provider=VFPOLEDB;Data source='+Justpath(m.tcDataSource)
    lcSQLStatement = Textmerge('select * from [<< JustStem(m.tcdatasource) >>]')
 
    *** set the LOCALEID to English
    nlLocaleId=Sys(3004)  && Save local id
    =Sys(3006,1033)    && We will be sending instructions in English
    *** set the LOCALEID to English
 
    oWordDocument=Createobject("word.application") && Create word object
    With oWordDocument
        loDoc = .documents.Add(m.tcTemplate)  && Open a template
 
        With .ActiveDocument.Mailmerge
            .OpenDataSource(m.lcSource, wdOpenFormatAuto,.F.,,.T.,,,,,,,m.lcConnection, m.lcSQLStatement)
            .EditMainDocument    && Activate the main document
            .Destination = wdSendToNewDocument
            .Execute()
 
        Endwith
        m.loDoc.Close(0) && closing the template doc - keep open to create your own template
        loDoc = null
        .ActiveDocument.SaveAs(m.tcSaveAs, wdFormatDocument97)
        .ActiveDocument.Saved = .T.
        .DisplayAlerts = wdAlertsNone
        .NormalTemplate.Saved = .T.
        For Each oDoc In .documents
            oDoc.Close(wdDoNotSaveChanges)
        Endfor
        oDoc = .Null.
        .Quit(wdDoNotSaveChanges)
    Endwith
    **** Set the LocaleId to the previous value
    =Sys(3006,Val(nlLocaleId))
    Wait clear
Endproc

11

Re: Word Dosyasına Bilgi Yazmak

biraz basit ve pratik bilgi olacak profesyonel degil ama iş görürü sanırım




d:\Sozlesme.doc
sablon dosyan olsun bunun içine personelin adının yazılacagı yere %m_peradi% yazarsan  işini görö gibi





m_personel="CİN ALİ GEL "



DELETE FILE GETENV("UserProfile")+"\Desktop\Sozlesme.doc"
COPY FILE "d:\Sozlesme.doc " TO GETENV("UserProfile")+"\Desktop\Sozlesme.doc"



m_dosya=GETENV("UserProfile")+"\Desktop\Sozlesme.doc"


Local oWord As Word.Application
oWord = CreateObject("Word.Application")
With oWord As WORD.Application
  .Documents.Open(m_dosya)
  .Visible = .T.
 
 
   With .Selection.Find
    .Text = "%m_peradi%"
    .Replacement.Text = &m_personel
    .Execute(,,,,,,,,,,2,,,,)
   ENDWITH
   



EndWith

oWord = .Null.

Bilgi Paylaşıldıkça Artar...!

12

Re: Word Dosyasına Bilgi Yazmak

&m_personel

derken:

m.m_personel

demek istedin sanirim:)

13

Re: Word Dosyasına Bilgi Yazmak

Herkese teşekkür ederim.
Sayın anteplinin önerisini internetten ararken buldum ve uyguladım.

Local oWord As "Word.Application"
oWord = CreateObject("Word.Application")
oDoc = oWord.Documents.Open("D:\Sozlesme.doc")

oRange = oWord.ActiveDocument.Content
With oRange.Find
    .Text = "Adı Soyadı            :"
    .Replacement.Text = "Adı Soyadı            :"+Alltrim(personel.adi_soyadi)
    .Execute( ,  , , , ,  , , , , ,  2)
EndWith

oWord.Visible = .T.

14

Re: Word Dosyasına Bilgi Yazmak

Neden oyle yapmamalisin onu da dusundunuz umarim:) Bul ve degistirin sakincalarini da hesaba katin.

15

Re: Word Dosyasına Bilgi Yazmak

cetinbasoz yazdı:

Neden oyle yapmamalisin onu da dusundunuz umarim:) Bul ve degistirin sakincalarini da hesaba katin.

Abicim kafam takıldı şimdi. Bende üç aşağı beş yukarı Antepli arkadaşın yaptığı gibi yapmıştım zamanında. Ve o zamandan beri sorunsuz bir şekilde çalışıyor. Acaba nasıl sakıncalar olabilir ki ?

Benim yaptığımda, word dökümanı içinde datadan gelen bilgileri koyacağım yere <yzAdSoyad>, <yzAdres> vb.. gibi taglar koymuştum. Ve sonrasında da

            lcDeger[yzAdSoyad]   = Alltrim(thisform.txtAdUnvan.Value)
            lcDeger[yzAdres]     = Alltrim(thisform.edtAdres.Value)

            DO while oSel.Find.Execute('\<*\>',,,.T.,,,.T.,1,,)
                lcFoundText=oWord.SELECTION.TEXT
                lcField = Substr(lcFoundText,2,Len(lcFoundText)-2)
                oWord.Selection.Find.Execute('\<'+lcField+'\>',,,,,,,,,lcDeger[&lcField])
            EndDo 

tarzında bir kodlama vardı. Sonuçta <> tag işaretleri arasında benim koyduğum değişken isimleri dışında word dökümanı içinde geçen başka bir bilgi olmadığına göre sadece bunları bulup, replace etmesi gerekmez mi ?

Tekin Başöz
Yapay Zeka Ltd.

16 Son düzenleyen, cetinbasoz (28.10.2014 18:16:43)

Re: Word Dosyasına Bilgi Yazmak

tbasoz yazdı:
cetinbasoz yazdı:

Neden oyle yapmamalisin onu da dusundunuz umarim:) Bul ve degistirin sakincalarini da hesaba katin.

Abicim kafam takıldı şimdi. Bende üç aşağı beş yukarı Antepli arkadaşın yaptığı gibi yapmıştım zamanında. Ve o zamandan beri sorunsuz bir şekilde çalışıyor. Acaba nasıl sakıncalar olabilir ki ?

Benim yaptığımda, word dökümanı içinde datadan gelen bilgileri koyacağım yere <yzAdSoyad>, <yzAdres> vb.. gibi taglar koymuştum. Ve sonrasında da

            lcDeger[yzAdSoyad]   = Alltrim(thisform.txtAdUnvan.Value)
            lcDeger[yzAdres]     = Alltrim(thisform.edtAdres.Value)

            DO while oSel.Find.Execute('\<*\>',,,.T.,,,.T.,1,,)
                lcFoundText=oWord.SELECTION.TEXT
                lcField = Substr(lcFoundText,2,Len(lcFoundText)-2)
                oWord.Selection.Find.Execute('\<'+lcField+'\>',,,,,,,,,lcDeger[&lcField])
            EndDo 

tarzında bir kodlama vardı. Sonuçta <> tag işaretleri arasında benim koyduğum değişken isimleri dışında word dökümanı içinde geçen başka bir bilgi olmadığına göre sadece bunları bulup, replace etmesi gerekmez mi ?

Canim kardesim, sen buralara ugrar miydin smile
Sen "tag" kullanmissin, duz metin degil, ondan avantajlisin. Ancak Find, "story" basina calisir. Eger bu taglari header, footer vs. gibi storylere alirsan o zaman calismayacak, hepsini dolasip update etmen gerekiyor. Bir de madem < > tag kullaniyorsun, o taglarin merge gibi bir fazlasi (chevron) zaten mailmerge field demek << >>. Yani sen dolayli olarak mergefield'i kesfetmissin smile Bir de su var, Find gibi cozumler tek bir dokuman icin. Oysa mailmerge, bir tek tablodan ayni anda N tane dokumani "merge" etmek icin. Yani 100 tane personelin de olsa, 1000 tane de olsa calistirdigin tek bir mailmerge. Ayni sablonu word kayit basina 'merge' ediyor, Ne bileyim, bizim yaptiklarimiz icinde en saglikli calisan bu oldu.