>I'm wondering if there is a way to identify, within a file index, what
>type of file operation has occurred.
Hello, Jeff.
Listed below is a program that uses the index like a trigger. It can only
detect WRITE and DELETE statements though. I used this approach with PI and
PI/open as they never supported triggers (unless one considered the AKUFS a
trigger).
I have not tried this approach on UniVerse so I can not speak to its
performance, however, I suspect it will work reasonably well. If you do give
it a try, please let me know your results.
Ask me questions about what it is doing if things are unclear. I published
an article in Infocus and an NPUG proceedings that describes the algorithm
in detail but I do not have that in electronic form. :-(
Best regards,
Gyle
**********************************************************
SUBROUTINE BUILD.POD.INDEX(result)
* This program projects a nested Purchase Order into a normalized form
suitable for reporting purposes.
$INCLUDE PO.EQUATE.INS.IBAS
$INCLUDE POD.EQUATE.INS.IBAS
DIM temporary.pod.record(2000)
DIM purchase.order.record(100)
EQUATE TRUE TO 1
EQUATE FALSE TO 0
EQUATE ADD TO 1
EQUATE DELETING TO 2
EQUATE UPDATE.FIRST.CALL TO 3
EQUATE UPDATE.SECOND.CALL TO 4
EQUATE NEEDLESS.WRITE.PERFORMED TO 5
EQUATE BUILDING.INDEX TO 6
COMMON /PO.POD/ Po.File.Variable,
Pod.File.Variable,
Last.Updated.Id,
Last.Mode,
Last.Added.Id,
Build.Time
result = ""
IF NOT(FILEINFO(Po.File.Variable, 0)) THEN
OPEN "", "PO" TO Po.File.Variable ELSE
PRINT
PRINT "Unable to open the PO file! (BUILD.POD.INDEX)"
RETURN
END
Last.Updated.Id = ""
Last.Added.Id = ""
Last.Mode = ""
Build.Time = 0
END
IF NOT(FILEINFO(Pod.File.Variable, 0)) THEN
OPEN "", "POD" TO Pod.File.Variable ELSE
PRINT
PRINT "Unable to open the POD file! (BUILD.POD.INDEX)"
RETURN
END
Last.Updated.Id = ""
Last.Added.Id = ""
Last.Mode = ""
Build.Time = 0
END
IF @SENTENCE[1, 11] = "BUILD.INDEX" THEN
Last.Mode = BUILDING.INDEX
END ELSE
Build.Time = 0
READ temporary.record FROM Po.File.Variable, @ID THEN
IF temporary.record = @RECORD THEN
BEGIN CASE
CASE @ID = Last.Updated.Id
Last.Mode = UPDATE.SECOND.CALL
Last.Added.Id = ""
CASE @ID = Last.Added.Id
Last.Mode = NEEDLESS.WRITE.PERFORMED
Last.Added.Id = ""
CASE TRUE
Last.Mode = ADD
Last.Added.Id = @ID
END CASE
Last.Updated.Id = ""
END ELSE
Last.Mode = UPDATE.FIRST.CALL
Last.Added.Id = ""
Last.Updated.Id = @ID
END
END ELSE
Last.Mode = DELETING
Last.Updated.Id = ""
Last.Added.Id = ""
temporary.record = ""
END
END
display.error.messages = TRUE
ON Last.Mode GOSUB add:,
delete:,
update:,
update.phase.2:,
needless.write.performed:,
build:
RETURN
add:
GOSUB build.pod.records:
IF result # "ERROR" THEN
GOSUB write.pod.records:
END
RETURN
delete:
display.error.messages = FALSE
GOSUB build.pod.records:
GOSUB delete.pod.records:
RETURN
update:
display.error.messages = FALSE
GOSUB build.pod.records:
IF result # "ERROR" THEN
GOSUB write.pod.records:
END
RETURN
update.phase.2:
GOSUB delete.pod.records:
GOSUB build.pod.records:
IF result # "ERROR" THEN
GOSUB write.pod.records:
END
RETURN
needless.write.performed:
display.error.messages = FALSE
GOSUB build.pod.records:
RETURN
build:
IF Build.Time = 0 THEN
PRINT "Clearing the POD file. (BUILD.POD.INDEX)"
CLEARFILE Pod.File.Variable
Build.Time = 1
END
GOSUB build.pod.records:
IF result # "ERROR" THEN
GOSUB write.pod.records:
END
RETURN
build.pod.records:
MATPARSE purchase.order.record FROM @RECORD, @FM
detail.record.counter = 0
errors = ""
result = ""
number.of.backordered.line.items = 0
number.of.excess.receipt.line.items = 0
customer.id = purchase.order.record(PO.VENDOR.NUMBER)
IF customer.id = "" THEN
customer.id = purchase.order.record(6)
END
customer.po = purchase.order.record(PO.PURCHASE.ORDER.NUMBER)
current.order.status = purchase.order.record(PO.STATUS)
hold = purchase.order.record(14)
purchase.order.type = purchase.order.record(27)
work.order.sequense = purchase.order.record(63)
* Process each line item
IF LEN(purchase.order.record(PO.LINE.ITEM)) THEN
line.item.position = 0
LOOP
REMOVE line.item FROM purchase.order.record(PO.LINE.ITEM)
SETTING delimiter
line.item.position += 1
part.number = purchase.order.record(PO.LINE.ITEM.PART.NUMBER)<1,
line.item.position>
part.description = purchase.order.record(PO.PART.DESCRIPTION)<1,
line.item.position>
quantity.ordered = purchase.order.record(PO.ORDER.QUANTITY)<1,
line.item.position>
unit.price = purchase.order.record(PO.UNIT.PRICE)<1,
line.item.position>
vendor.description =
purchase.order.record(PO.VENDOR.DESCRIPTION)<1, line.item.position>
product.manager = purchase.order.record(PO.PROD.MANAGER)<1,
line.item.position>
condition = purchase.order.record(PO.CONDITION)<1,
line.item.position>
production.notes = purchase.order.record(PO.PRODUCTION.NOTES)<1,
line.item.position>
brokerage.po = purchase.order.record(PO.BROKERAGE.PO)<1,
line.item.position>
manufacturer.code =
purchase.order.record(PO.MANUFACTURER.CODE)<1, line.item.position>
trans.code = purchase.order.record(PO.TRANS.CODE)<1,
line.item.position>
print.flag = purchase.order.record(71)<1, line.item.position>
license.code = purchase.order.record(PO.LICENSE.CODE)<1,
line.item.position>
line.item.hold = purchase.order.record(PO.ITEM.HOLD)<1,
line.item.position>
ncon = purchase.order.record(PO.NCON)<1, line.item.position>
dpac = purchase.order.record(PO.DPAC)<1, line.item.position>
revision.level = purchase.order.record(PO.REVISION)<1,
line.item.position>
back.order.quantity =
purchase.order.record(PO.BACK.ORDER.QUANTITY)<1, line.item.position>
bums = purchase.order.record(PO.BUMS)<1, line.item.position>
lsta = purchase.order.record(PO.LSTA)<1, line.item.position>
change.notes = purchase.order.record(PO.CHANGE.NOTES)<1,
line.item.position>
line.notes = purchase.order.record(PO.LINE.NOTES)<1,
line.item.position>
receipts.field = purchase.order.record(39)<1,
line.item.position>
scheduled.receipts.field = purchase.order.record(34)<1,
line.item.position>
target.dates.field = purchase.order.record(70)<1,
line.item.position>
*---- Check integrity of key data
line.errors = ""
IF NOT(NUM(quantity.ordered)) THEN
line.errors<-1> = " The order quantity is invalid."
END
IF NOT(NUM(back.order.quantity)) THEN
line.errors<-1> = " The back order quantity is invalid."
END
IF NOT(NUM(unit.price)) THEN
line.errors<-1> = " The unit price is invalid."
END
IF LEN(line.errors) THEN
errors<-1> = "Line item number : " : line.item : " is
incorrect!"
errors<-1> = line.errors
END ELSE
*---- Build skeleton detail record
po.detail.record = ""
po.detail.record<POD.LINE.ITEM.NUMBER> = line.item
po.detail.record<POD.PART.NUMBER> = part.number
po.detail.record<POD.PART.DESCRIPTION> = part.description
po.detail.record<POD.BUMS> = bums
po.detail.record<POD.DPAC> = dpac
po.detail.record<POD.PO.TYPE> = purchase.order.type
po.detail.record<POD.PMGR> = product.manager
po.detail.record<POD.VEND.DESCRIPTION> = vendor.description
po.detail.record<POD.UNIT.PRICE> = unit.price
po.detail.record<POD.LI.HOLD> = line.item.hold
po.detail.record<POD.REVISION> = revision.level
po.detail.record<POD.WO.SEQ.NUMBER> = work.order.sequense
po.detail.record<POD.DATE.CREATED> = DATE()
po.detail.record<25> = condition
po.detail.record<26> = line.notes
po.detail.record<27> = change.notes
*---- Calculate the status of this line item
GOSUB calculate.line.item.status:
*---- Build all necessary detail records
IF there.are.backorders THEN
GOSUB build.scheduled.receipt.records:
END
IF there.are.receipts THEN
GOSUB build.receipt.records:
END
IF there.are.excess.receipts THEN
GOSUB build.excess.receipt.records:
END
IF total.line.item.scheduled.receipt.quantity = 0 THEN
GOSUB add.cancel.line:
END
END
WHILE delimiter DO REPEAT
IF LEN(errors) THEN
result = "ERRORS"
IF display.error.messages THEN
IF Last.Mode = BUILDING.INDEX THEN
PRINT
END
PRINT "PO# : " : @ID : " has incorrect data. The problems
are listed below." : @SYS.BELL
LOOP
PRINT REMOVE(errors, delimiter)
WHILE delimiter DO REPEAT
PRINT "No further processing of this order is possible until
this problem"
PRINT "is corrected."
END
END ELSE
BEGIN CASE
CASE current.order.status = "T"
result = ""
CASE (number.of.backordered.line.items > 0) OR
(number.of.excess.receipt.line.items > 0)
IF current.order.status # "B" THEN
result = "B"
END
CASE TRUE
IF current.order.status # "C" THEN
result = "C"
END
END CASE
END
END
RETURN
add.cancel.line:
scheduled.receipts.field = scheduled.receipts.field
LOOP
REMOVE scheduled.receipts FROM scheduled.receipts.field SETTING
minor.delimiter
REMOVE original.dates FROM target.dates.field SETTING
original.delimiter
scheduled.receipt.date = FIELD(scheduled.receipts, "*", 1)
scheduled.receipt.quantity = FIELD(scheduled.receipts, "*", 2)
original.date = FIELD(original.dates, "*",1)
po.detail.record<POD.SHIP.DATE> = scheduled.receipt.date
po.detail.record<POD.QUANTITY> = scheduled.receipt.quantity
po.detail.record<POD.CUSTOMER.ID> = customer.id
po.detail.record<POD.PAYDATE> = ""
po.detail.record<POD.DETAIL.TYPE> = "C"
po.detail.record<28> = original.date
detail.record.counter += 1
temporary.pod.record(detail.record.counter) = po.detail.record
UNTIL minor.delimiter = 0 REPEAT
RETURN
calculate.line.item.status:
total.line.item.received.quantity = 0
IF LEN(receipts.field) THEN
receipts.field = receipts.field
there.are.receipts = TRUE
LOOP
REMOVE receipts FROM receipts.field SETTING minor.delimiter
receipts.quantity = FIELD(receipts, "*", 2)
total.line.item.received.quantity += receipts.quantity
WHILE minor.delimiter DO REPEAT
END ELSE
there.are.receipts = FALSE
END
total.line.item.scheduled.receipt.quantity = 0
IF LEN(scheduled.receipts.field) THEN
scheduled.receipts.field = scheduled.receipts.field
LOOP
REMOVE scheduled.receipt FROM scheduled.receipts.field SETTING
minor.delimiter
scheduled.receipt.quantity = FIELD(scheduled.receipt, "*", 2)
total.line.item.scheduled.receipt.quantity +=
scheduled.receipt.quantity
WHILE minor.delimiter DO REPEAT
END
total.line.item.backorder.quantity =
total.line.item.scheduled.receipt.quantity -
total.line.item.received.quantity
there.are.backorders = FALSE
there.are.excess.receipts = FALSE
BEGIN CASE
CASE total.line.item.backorder.quantity = 0
CASE total.line.item.backorder.quantity > 0
there.are.backorders = TRUE
number.of.backordered.line.items += 1
CASE total.line.item.backorder.quantity < 0
there.are.excess.receipts = TRUE
number.of.excess.receipt.line.items += 1
END CASE
RETURN
build.receipt.records:
target.dates.quantities = purchase.order.record(70)<1,
line.item.position>
save.original.date = ""
GOSUB get.original.schedule.date:
receipts.total = 0
receipts.field = receipts.field
LOOP
REMOVE receipts FROM receipts.field SETTING minor.delimiter
receipts.date = FIELD(receipts, "*", 1)
receipts.quantity = FIELD(receipts, "*", 2)
receipts.number = FIELD(receipts, "*", 3)
receipts.payment.flag = FIELD(receipts, "*", 4)
po.detail.record<POD.SHIP.DATE> = receipts.date
po.detail.record<POD.QUANTITY> = receipts.quantity
po.detail.record<POD.CUSTOMER.ID> = customer.id : "*" :
receipts.number
po.detail.record<POD.PAYDATE> = receipts.payment.flag
po.detail.record<POD.DETAIL.TYPE> = "S"
receipts.total += receipts.quantity
IF receipts.total GT original.quantity THEN
receipts.total = 0
GOSUB get.original.schedule.date:
END
po.detail.record<28> = original.date
detail.record.counter += 1
temporary.pod.record(detail.record.counter) = po.detail.record
WHILE minor.delimiter DO REPEAT
date.of.last.receipt = receipts.date
RETURN
get.original.schedule.date:
REMOVE original.date.quantity FROM target.dates.quantities SETTING
original.delimiter
original.date = FIELD(original.date.quantity, "*",1)
original.quantity = FIELD(original.date.quantity, "*",2)
IF original.date = "" THEN
original.date = save.original.date
END ELSE
save.original.date = original.date
END
RETURN
build.scheduled.receipt.records:
scheduled.receipts.field = scheduled.receipts.field
total.scheduled.receipts = 0
total.receipts = total.line.item.received.quantity ;* start with
all real receipts
LOOP
REMOVE scheduled.receipts FROM scheduled.receipts.field SETTING
minor.delimiter
REMOVE original.dates FROM target.dates.field SETTING
original.delimiter
scheduled.receipt.date = FIELD(scheduled.receipts, "*", 1)
scheduled.receipt.quantity = FIELD(scheduled.receipts, "*", 2)
original.date = FIELD(original.dates, "*",1)
total.scheduled.receipts += scheduled.receipt.quantity
IF total.scheduled.receipts > total.receipts THEN
backorder.quantity = total.scheduled.receipts - total.receipts
IF backorder.quantity > total.line.item.backorder.quantity THEN
backorder.quantity = total.line.item.backorder.quantity
END
total.receipts += backorder.quantity ;* add in scheduled
receipts
po.detail.record<POD.SHIP.DATE> = scheduled.receipt.date
po.detail.record<POD.QUANTITY> = backorder.quantity
po.detail.record<POD.CUSTOMER.ID> = customer.id
po.detail.record<POD.PAYDATE> = ""
po.detail.record<POD.DETAIL.TYPE> = "B"
po.detail.record<28> = original.date
detail.record.counter += 1
temporary.pod.record(detail.record.counter) = po.detail.record
END
WHILE minor.delimiter DO REPEAT
RETURN
build.excess.receipt.records:
po.detail.record<POD.SHIP.DATE> = date.of.last.receipt
po.detail.record<POD.QUANTITY> =
ABS(total.line.item.backorder.quantity)
po.detail.record<POD.PAYDATE> = ""
po.detail.record<POD.DETAIL.TYPE> = "O"
po.detail.record<28> = original.date
detail.record.counter += 1
temporary.pod.record(detail.record.counter) = po.detail.record
RETURN
write.pod.records:
FOR I = 1 TO detail.record.counter
WRITE temporary.pod.record(I) TO Pod.File.Variable, I : '*' : @ID
NEXT I
RETURN
delete.pod.records:
pod.sequence.number = 0
end.of.pods = FALSE
LOOP
pod.sequence.number += 1
READ dummy FROM Pod.File.Variable, pod.sequence.number : "*" : @ID
ELSE
end.of.pods = TRUE
END
UNTIL end.of.pods DO
DELETE Pod.File.Variable, pod.sequence.number : "*" : @ID
REPEAT
dummy = ""
RETURN
END
-------
u2-users mailing list
[email protected]
To unsubscribe please visit http://listserver.u2ug.org/