home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d09xx / d0925.lha / DonsGenies / DonsGenies.lha / Don'sGenies / MailMerge2.pprx < prev    next >
Text File  |  1993-02-28  |  8KB  |  315 lines

  1. /*
  2. @BMailMerge  @P@ICopyright Gold Disk Inc., Jan, 1993. Close-up added by Don Cox, Feb.93.
  3.  
  4. This genie will load a tab or comma delimited merge file and print multiple copies of the current document. It will substitute the merge string in appropriate places. In this version, if the names of the fields end in a numeral (e.g. ADDR1, ADDR2, etc), blank lines will be closed up.
  5.  
  6. In order to delimit a field as a merge field, you must surround the merge
  7. text with double guillemots. Example:½½Name╗╗
  8.    Open guillemot: alt-9
  9.    Closing guillemot: alt-0
  10. */
  11.  
  12. parse arg filename
  13. if ~show(l, "rexxsupport.library") then
  14.     if ~addlib("rexxsupport.library",0,-30) then
  15.         call exit_msg("Please install the rexxsupport.library in your libs: directory before running this Genie")
  16.  
  17. signal on error
  18. signal on syntax
  19. signal on break_c
  20. signal on break_d
  21. signal on break_e
  22. signal on halt
  23. signal on ioerr
  24. address command
  25. call SafeEndEdit.rexx()
  26. call ppm_SetBatchMode(1)
  27. call ppm_AutoUpdate(0)
  28. cr = '0a'x
  29.  
  30. npages  = ppm_NumPages()
  31. if npages = 0 then exit_msg("You must have a merge document prepared to run this Genie.")
  32.  
  33. if filename = '' then
  34.     filename = ppm_GetFileName("Select Merge File","", "")
  35.  
  36. if filename = '' then exit_msg()
  37.  
  38. if ~open(file, filename, "r") then
  39.     call exit_msg("Unable to open "file)
  40.  
  41.  
  42. line = readln(file)
  43.  
  44. delimiter = ''
  45. matrix. = ""  /* null string for unfilled positions */
  46.  
  47. if pos('",', line) ~= 0 then do
  48.     delimiter   = '",'  /* Look for ",  */
  49.     qt          = '"'   /* Look for inchmark */
  50.     rparseline  = "parse var line matrix.0.fields '"delimiter"' line"
  51.     parseline   = "parse var line datum '"delimiter"' line"
  52.     rstripline  = "matrix.0.fields = upper(strip(matrix.0.fields, b, '"qt"'))"
  53.     stripline   = "datum = strip(datum, b,'"qt"')"
  54.     end
  55.  
  56. else if pos('09'x, line) ~= 0 then do  /* Look for tabs */
  57.     rparseline  = "parse var line matrix.0.fields '09'x line"
  58.     parseline   = "parse var line datum '09'x line"
  59.     rstripline  = "matrix.0.fields = upper(strip(matrix.0.fields))"
  60.     stripline   = "datum = strip(datum)"
  61.     end
  62.  
  63. else if length(line) < 255 then do  /* single items, no delimiters  */
  64.     rparseline  = "matrix.0.fields = upper(strip(line));line = ''"
  65.     parseline   = "datum = strip(line);line = ''"
  66.     stripline   = "/**/"
  67.     rstripline  = "/**/"
  68.     end
  69.  
  70. else
  71.     exit_msg("File must be either comma delimited or tab delimited")
  72.  
  73.  
  74. fields = 0
  75. records  = 0
  76. do while line ~ = ''  /* Process first line, listing the fields */
  77.  
  78.     fields = fields + 1  /* Count fields */
  79.     interpret rparseline
  80.     interpret rstripline
  81. end
  82.  
  83. /* Now process the data lines, building up the matrix */
  84.  
  85. do while ~eof(file)
  86.  
  87.     line = readln(file)
  88.  
  89.     if line = '' then iterate
  90.  
  91.     records = records + 1
  92.  
  93.     call ppm_ShowStatus("Importing record "records)
  94.  
  95.     field = 1
  96.     counter = 1
  97.     do until counter = fields+1
  98.  
  99.         interpret parseline  /* These are the data lines */
  100.         interpret stripline
  101.         testdigit = right(matrix.0.counter,1)
  102.         if ~datatype(testdigit,"n") then field = counter
  103.         counter = counter+1
  104.         matrix.records.field = datum
  105.         if datum ~="" then field = field+1
  106.         if line = '' then leave
  107.     end
  108. end
  109.  
  110. call close(file)
  111.  
  112. call ppm_ShowStatus("Preparing document for mail merge..")
  113. boxes   = 1
  114.  
  115. call analyzeboxes()
  116.  
  117. reccount = 1
  118. boxnum  = 1
  119. btext   = 1
  120. ctext   = 2
  121. field   = 1
  122.  
  123. if doctext.0 < 1 then exit_msg("No merge codes found")
  124.  
  125. do while reccount <= records
  126.  
  127.     do boxes = 1 to doctext.0
  128.  
  129.         box = doctext.boxes
  130.         tlen    = 0
  131.  
  132.         boxtext = doctext.boxes.btext
  133.  
  134.         do mergpos = 1 to doctext.boxes.btext.0
  135.  
  136.             field   = doctext.boxes.btext.mergpos.1
  137.             if field = 'NEXT' then do
  138.                 reccount = reccount + 1
  139.                 ftext   = ''
  140.                 end
  141.  
  142.             else if left(field, 1) = '=' then do /* Interpret any ARexx expression */
  143.                 string = ''
  144.                 address command
  145.                 interpret "string "field
  146.                 address  /* back to PPage port */
  147.  
  148.                 ftext = string
  149.                 end
  150.  
  151.             else
  152.                 ftext   = matrix.reccount.field
  153.  
  154.             fpos    = doctext.boxes.btext.mergpos
  155.             boxtext = insert(ftext, boxtext, fpos - 1 + tlen)
  156.             tlen    = tlen + length(ftext)
  157.  
  158.         end
  159.  
  160.         call ppm_ShowStatus("Merging record "reccount" of "records)
  161.                 call ppm_DeleteContents(box)
  162.                 call ppm_TextIntoBox(box, boxtext)
  163.  
  164.     end
  165.  
  166.     reccount = reccount + 1
  167.  
  168.     lastpage = ppm_DocLastPage()
  169.  
  170.     do page = 1 to npages
  171.  
  172.         call ppm_CopyPage(page, lastpage + 1, 1)
  173.         lastpage = lastpage + 1
  174.  
  175.     end
  176.  
  177.  
  178. end
  179.  
  180. do i = 1 to doctext.0
  181.  
  182.     box = doctext.i
  183.     text    = doctext.i.2
  184.  
  185.         call ppm_DeleteContents(box)
  186.         call ppm_TextIntoBox(box, text)
  187.         call ppm_SetBoxUserData(box, "")
  188.  
  189. end
  190.  
  191. exit_msg("Done")
  192.  
  193.  
  194. exit_msg: procedure
  195. do
  196.     parse arg message
  197.  
  198.     if message ~= '' then call ppm_Inform(1,message,)
  199.     call ppm_SetBatchMode(0)
  200.     call ppm_ClearStatus()
  201.     call ppm_AutoUpdate(1)
  202.     exit
  203. end
  204.  
  205.  
  206. analyzeboxes: procedure expose doctext. matrix. fields
  207. do
  208.         randval = (randu() * time(s)) % 1
  209.     boxnum  = 1
  210.     rpos    = 1
  211.     btext   = 1
  212.     ctext   = 2
  213.     field   = 1
  214.  
  215.     box = ppm_DocFirstBox()
  216.  
  217.     do while box ~= 0
  218.  
  219.         if upper(word(ppm_GetBoxInfo(box), 1)) ~= TEXT | ppm_GetBoxUserData(box) = randval then
  220.         do
  221.             box = ppm_DocNextBox(box)
  222.             iterate
  223.         end
  224.  
  225.                 oldbox = box
  226.                 box = ppm_ArtFirstBox(box)
  227.                 boxtext = ppm_GetArticleText(box, 1)
  228.  
  229.         copy    = boxtext
  230.         fpos    = pos('½½', boxtext)
  231.  
  232.         if fpos ~= 0 then
  233.         do
  234.             doctext.boxnum  = box
  235.             rpos    = 1
  236.  
  237.             do while fpos ~= 0
  238.                                 found = 0
  239.                 epos    = pos('╗╗', boxtext, fpos)
  240.                 if epos = 0 then leave
  241.                 fieldlen    = epos - fpos + 2
  242.                 temptext   = strip(substr(boxtext, fpos + 2, fieldlen - 4))
  243.                 fieldtext   = upper(temptext)
  244.                 if fieldtext = 'NEXT'  then
  245.                                 do
  246.                                         found    = 1
  247.                     fieldnum = 'NEXT'
  248.                                 end
  249.                 else if left(fieldtext, 1) = '=' then
  250.                                 do
  251.                                         found    = 1
  252.                     fieldnum = temptext
  253.                                 end
  254.                 else
  255.                 do fieldnum = 1 to fields
  256.  
  257.                     if matrix.0.fieldnum = fieldtext then
  258.                                         do
  259.                                                 found = 1
  260.                                                 leave fieldnum
  261.                                         end
  262.                 end
  263.  
  264.                                 if found then
  265.                                 do
  266.                         boxtext = delstr(boxtext, fpos, fieldlen)
  267.                         doctext.boxnum.btext.rpos = fpos
  268.                         doctext.boxnum.btext.rpos.1 = fieldnum
  269.                         rpos = rpos + 1
  270.                                 end
  271.  
  272.                                 fpos = pos('½½', boxtext, fpos + 1)
  273.             end
  274.  
  275.             doctext.boxnum.btext = boxtext
  276.             doctext.boxnum.ctext = copy
  277.  
  278.             doctext.boxnum.btext.0 = rpos - 1
  279.             doctext.0   = boxnum
  280.             boxnum  = boxnum + 1
  281.  
  282.         end
  283.  
  284.                 do while box ~= 0
  285.  
  286.                         call SetBoxUserData(box, randval)
  287.                         box = ppm_ArtNextBox(box)
  288.  
  289.                 end
  290.  
  291.         box = ppm_DocNextBox(oldbox)
  292.  
  293.     end
  294.  
  295.     return
  296.  
  297. end
  298.  
  299.  
  300.  
  301. error:
  302. syntax:
  303. break_c:
  304. break_d:
  305. break_e:
  306. break_f:
  307. halt:
  308. ioerr:
  309. novalue:
  310. do
  311.     call ppm_Inform(1,"An Arexx error has occured interpeting Arexx string: "errortext(rc)" Line "SIGL,)
  312.     return
  313. end
  314.  
  315.