Good afternoon Rob,
I hope your day is going well. I have what I think may be a similar scenario - except the PDF file I generate is a certificate of completion for each student. Are you attempting to accomplish this task for all students (individually) with one button, or do you want to choose students on an individual basis?
Yes, seems similar and your question actually made me pause and think. It will be nice if the creation of all individual report cards can be accomplished by push of one button but also have another button to create "a" report card on-demand so to speak (since the FMPv12 supplied button creates only a single PDF for all record).
Honestly, though, I want to make sure we can create individual PDF files on time to distribute to parents, including myself so I can forgo the second option. Also with input from others in my previous questions, I need to jump on normalizing the database as soon as I get this done.
So any direction towards the light will be appreciated
Have a good weekend Bill!
I'd like to ask you one more question regarding the generation of the PDF file you mentioned and its intended use. Do you need to produce a printed copy of this document only, or do you need to save this as a PDF for some reason and print it? Thanks.
The latter - save as PDF. I'm reading a book, two books, to see how I can concat some unique filename from table field and even insert into blob field. That way I can distro thru Email attachment & leave the printing to parents.
If I do stumble upon an answer to the single record PDF creation in the book I'll report back here but seems like you already do something similar
I was even thinking of duct-tape method of looping:
- move a record into a table with layout,
- concat unique filename
- save as PDF
- insert into blob field in original table where a single record was copied from
- delete record from table with layout
- repeat until all student records processed from original table.
The method I've used is similar to looping method you described. Though in my method the email generation - including the subject line, body of the message, and attachment of the PDF - is included in the loop. So the final output would be an email addressed to the parents containing a subject line which includes the student's name, a message in the body including the specific details regarding the report card date, and the attachment.
In my case, I like to review the email prior to it being sent, but I believe the send process can be automated as well...so, click the button, grab a cup of coffee (if you have a large number of students) and wait for the process to complete. Then, if you feel it necessary, check your email sent items folder when it's finished to verify no one was left out.
If my method seems like it would work for your specific needs, I would gladly share the code I developed. I don't think it would require much modification to suit your purpose. Have a great day!
Wow, I'll appreciate it if you can share your methodology; that will give me a jump and help me divert my midnight engineering - aka volunteer hours - to the next steps of normalizing the database and building upon this initial try for the next quarter.
Thank you again Bill!
Here is the way I would tackle the challenge of producing student report cards:
- Create a layout that displays all the student records for which you wish to generate report cards (I'll refer to this layout as StudentRecords)
- Create a layout that displays a single report card record formatted the way you want the parents to view it (I’ll refer to this layout as ReportCard)
- Create a button on the StudentRecords layout that runs a script that does the following:
- Store the Desktop path - including the filename - in a variable (e.g, Set Variable [$DesktopPath; Value; Get ( DesktopPath ) & “ReportCard”]
- Sorts the records how ever you see fit
- Go to the first record
- Start a loop
- Store the primary key for the record in a local variable (e.g., $StudentID)
- Open a new window
- Enter Find Mode - Entering find mode before moving to the next layout will prevent the layout you’re going to call next from retrieving all the records associated with the table that it is based on.
- Go to the ReportCard layout
- Perform find using the $StudentID variable as the criteria - this should populate all the appropriate fields on the ReportCard layout.
- Save Records as PDF
- Select the Perform without dialog option
- Select Specify output option: use the $DesktopPath as the output option
- Send Mail
- Using this step instead of the “Create email with file as attachment”, which is an available option in the Save as PDF script step, provides more options to configure the email itself.
- Attach the file you saved to your desktop by specifying the variable you used to save it (i.e. $DesktopPath)
- After you have tested the final result you can choose to proceed through this step without a confirmation dialog. NOTE: You can use a calculation to include dynamic information in the text of the email To, Subject, and Message fields.
- Close current window
- Go to next record - Specify Exit after last
- End Loop
- Show Custom Dialog - Task complete
You'll obviously have some debugging to perform in order to get the final results you're after, but hopefully this method will help you find the way that works for you. As with most all things FileMaker, there are numerous ways to accomplish most any task. Everyone's methods change as they gain experience. That said, the best advice I can offer is to find any way you can to make your solution work and then strive to make it better (i.e. more efficient and more polished). In the end, you'll always accomplish more by learning as you go than you will by trying to learn everything before you act. Please let me know how your project goes. Have a great weekend!
Thank you for the pseudo code - I'm going to try mimicking it.
Your advice of "find any way you can to make your solution work and then strive to make it better" is very much appreciated as that is the route I was going to take after the initial duct-taping to make the deadline. Although you have given pointed me in the right direction with above pseudo so my initial solution will hopefully be more than duct-tape Keep you posted!
A couple of points:
1. Instead of using the Enter Find Mode, go to layout, find the ID of the student in the variable, you can use the Go To Related Records command.
Start on record 1. Use Go To Related Records, provided you have a relationship between students and grades or whatever table your report card layout is based on. Use that relationship to directly to their records. If you need to find the current year or quarter, you could accomplish that through various means, and I can explain those later if need-be. Use the GTRR command and open in a new window. This simply is a quicker way to get to the records you want. Then, as Bill is suggesting, save the PDF.
2. Instead of Desktop path, you could use Get (TemporaryPath). That way the actual PDF isn't saved on the user's harddrive.
The code Bill provided seems to be the best way, with the replacement of the enter find mode, etc with the GTRR. There can be such a thing as premature optimization. Get it working. If it doesn't take too long or hang up in anyway, that method is fine. I can't think of another way to do it, so this is probably the best approach.
My first database was a school system. I have two others that I'm working on now, so feel free to ask any other questions pertaining to that structure!
I agree with using Get ( TemporaryPath ). This leaves FM completely in control. You might also consider keeping a copy of the PDF reports in the database itself, perhaps in a separate table set up for the purpose, and obviously linked to the source record. All of this could be accomplished as part of the same script, and it preserves the PDF as a snapshot in time, for future reference. If you use external storage and the PDF is stored in a container while it is still in FM's temporary folder, the one FM stores will be retained even after the temporary one is zapped.
When I first started generating documents from my business management DB (quotes, invoices, letters, etc) I soon realised that these records needed to be stored in addition to the database from whence they came—for the taxman, if nothing else! To me it is much easier to keep "published" document rather than have to go back in time within your DB if you should ever need to print it or view it again some time later.
Thank you Jeremy for your inputs! I'll keep this thread updated
Thank you keywords.
Yes, after I try to mimic Bill's pseudo code, my goal for this initial quarter is to put the PDFs into the database at end o script. I need to understand your first paragraph better because it sounds like the method is just what I need.
Yes, the PDF is akin to your record for taxman and I'm sure the school doesn't want to recreate PDF based on historical records if requests are made for resend/transcripts to other schools, etc.
Forward movement - thank you to all for the continued dialog and teaching this old dog new tricks
Following Bill's pseudocode, immediately after you send the mail:
• create a new record in the pdf storage table; (1) insert the studentID that you already have held as a variable, in order to link this pdf document record to the student it concerns; (2) insert the pdf into the container field from the temporary file; (3) add any additional info needed in the record (which you should have gathered as $variable/s)
• carry on with the rest of the script.
Good morning everyone,
This is a fantastic community! So many people are willing to assist those of us who are less experienced. I would use Jeremy's Get (TemporaryPath) suggestion, it's a much better option.
As for the Go To Related Record step, would someone confirm for me that it only moves the record you specify from the server to the client (I realize that FileMaker Server may not be part of everyone's infrastructure)? I will be implementing mobile device access into some of my solutions in the very near future, so I'm doing my best to design with performance in mind.
Saving the PDF files back to the database is also a good idea if you need access to them later; storage is cheap. In my case, we chose to only save documents that contained information that the database was incapable of generating (e.g., a signature), and created reports that could be easily and quickly reproduced (e.g., all training conducted for a specific student or client) with a button click and user input of some basic criteria.
Thanks so much for pointing out ways to make my method of accomplishing this task more efficient...it's always a pleasure to learn a better way of achieving a goal! Have a great day