Can anyone see what is going on with the PROC DOCUMENT below?
PROC DOCUMENT name=work.forreplay(write);
/* Site 1 */
MAKE site1;
/* COPY \work.overview1\Print#1\Print#1 to site1;*/
SETLABEL site1 "Site: 1";
/* Group 1 */
MAKE site1\group1;
SETLABEL site1\group1 "Group 1";
MAKE site1\group1\past1_1;
COPY \work.past1_1\Print#1\Print#1 to site1\group1\past1_1;
SETLABEL site1\group1\past1_1 "Past";
MAKE site1\group1\pres1_1;
COPY \work.pres1_1\Print#1\Print#1 to site1\group1\pres1_1;
SETLABEL site1\group1\pres1_1 "Present";
MAKE site1\group1\fut1_1;
COPY \work.fut1_1\Print#1\Print#1 to site1\group1\fut1_1;
SETLABEL site1\group1\fut1_1 "Future";
/* Group 2 */
MAKE site1\group2;
SETLABEL site1\group2 "Group 2";
MAKE site1\group2\past1_2;
COPY \work.past1_2\Print#1\Print#1 to site1\group2\past1_2;
SETLABEL site1\group2\past1_2 "Past";
MAKE site1\group2\pres1_2;
COPY \work.pres1_2\Print#1\Print#1 to site1\group2\pres1_2;
SETLABEL site1\group2\pres1_2 "Present";
MAKE site1\group2\fut1_2;
COPY \work.fut1_2\Print#1\Print#1 to site1\group2\fut1_2;
SETLABEL \site1\group2\fut1_2 "Future";
/* Site 2 */
MAKE site2;
SETLABEL site2 "Site: 2";
/* Group 3 */
MAKE site2\group1;
SETLABEL site2\group1 "Group 3";
MAKE site2\group1\past2_1;
COPY \work.past2_1\Print#1\Print#1 to site2\group1\past2_1;
SETLABEL site2\group1\past2_1 "Past";
MAKE site2\group1\pres2_1;
COPY \work.pres2_1\Print#1\Print#1 to site2\group1\pres2_1;
SETLABEL site2\group1\pres2_1 "Present";
MAKE site2\group1\fut2_1;
COPY \work.fut2_1\Print#1\Print#1 to site2\group1\fut2_1;
SETLABEL site2\group1\fut2_1 "Future";
RUN;
ODS document close;
I created a bunch of outputs each into a separate ODS DOCUMENT, there will be lots of them in the end over lots of sites and groups (c.1000 in all).
But first I am testing with just a couple. As it stands it works as expect when I replay to PDF.
The bookmarks are as I want them in a hierarchy.
-->Site1
---->Group1
------>Past
------>Present
------>Future
---->Group2
------>Past
------>Present
-->Site2
---->Group3
------>Past
------>Present
------>Future
------>Future
However when I uncomment the COPY under /*Site 1*/, I get an error
ERROR: Invalid document path \Work.Forreplay\site1\group1
Am I missing something here? This copy is supposed to copy an overall Site report so is important.
Note1: All outputs are created and available. If I move the copy of issue to the end it runs fine, just puts that output at the end of the report where I do not want it.
Note2: This is a small sample, in the end I will create the PROC DOCUMENT code using some call execute statements to produce the 1000's of outputs needed. This has been tested with the same issues as above.
Thanks
SwissC
To make this a little simpler,
Of the three code samples below the first two worked fine, but when I tried to combine them in the third it threw an error that it could not find \site1\group1
PROC DOCUMENT name=work.a(write);
/* Site 1 */
MAKE site1;
SETLABEL site1 "Site: 1";
/* Group 1 */
MAKE site1\group1;
SETLABEL site1\group1 "Group 1";
MAKE site1\group1\past1_1;
COPY \work.past1_1\Print#1\Print#1 to site1\group1\past1_1;
SETLABEL site1\group1\past1_1 "Past";
RUN;
ODS document close;
PROC DOCUMENT name=work.b(write);
/* Site 1 */
MAKE site1;
COPY \work.overview1\Print#1\Print#1 to site1;
SETLABEL site1 "Site: 1";
RUN;
ODS document close;
PROC DOCUMENT name=work.c(write);
/* Site 1 */
MAKE site1;
COPY \work.overview1\Print#1\Print#1 to site1;
SETLABEL site1 "Site: 1";
/* Group 1 */
MAKE site1\group1;
SETLABEL site1\group1 "Group 1";
MAKE site1\group1\past1_1;
COPY \work.past1_1\Print#1\Print#1 to site1\group1\past1_1;
SETLABEL site1\group1\past1_1 "Past";
RUN;
ODS document close;
Eventually I managed to get Gemini (not the best idea for coding) to give me a working solution by using some DIR commands at the top level.
PROC DOCUMENT name=work.c(write);
/* Site 1 */
MAKE site1;
SETLABEL site1 "Site: 1";
DIR site1;
COPY \work.overview1\Print#1\Print#1 to ^;
DIR ^^;
/* Group 1 */
MAKE site1\group1;
SETLABEL site1\group1 "Group 1";
MAKE site1\group1\past1_1;
COPY \work.past1_1\Print#1\Print#1 to site1\group1\past1_1;
SETLABEL site1\group1\past1_1 "Past";
RUN;
ODS document close;
Still not sure why exactly it did not work, I am assuming something to do with it being the top level. Will try and investigate further when I get a chance with a different AI model.
@SwissC wrote:
Not sure if you see the same but in my view of the page, the code box is not displaying correctly, I did honestly but each line of code on separate lines.
I fixed the code block for you. It's a weird bug in the message interface. Not your fault.
@SwissC wrote:
Not sure if you see the same but in my view of the page, the code box is not displaying correctly, I did honestly but each line of code on separate lines.
That happens when you edit the text inside the code block in the normal editor window instead of the code box pop-up window. Put the cursor inside the code box and push the icon to get the pop-up to appear and then close the pop-up and the line breaks should be fixed.
I don't know PROC DOCUMENT well, but I've been playing with AI for SAS coding, so please take below suggestions with a large grain of salt.
AI points to a small typo in your code. This line has a leading backslash you don't want:
SETLABEL \site1\group2\fut1_2 "Future";
but that's probably not the cause of the problem. AI also claims:
"
That behavior is consistent with PROC DOCUMENT building the tree top-down and resolving paths as it goes. When COPY \work.overview1\Print#1\Print#1 to site1; runs at the top, SAS is touching site1 before the rest of the site1\group1 branch exists. If that copied object changes the current document context or occupies site1 as a node in a way SAS doesn’t expect, later MAKE site1\group1; can be seen as an invalid path. When you move the COPY to the bottom, the full site1 subtree already exists, so the copy lands in a valid destination and the error disappears.
The safe pattern here is: create all parent nodes first with MAKE, then do the COPYs, then SETLABELs. If you want, I can rewrite the block into a clean order that avoids this class of PROC DOCUMENT path errors.
"
And it then rewrote the code to:
proc document name=work.forreplay(write);
/* Site 1 */
make site1;
setlabel site1 "Site: 1";
/* Group 1 */
make site1\group1;
setlabel site1\group1 "Group 1";
make site1\group1\past1_1;
setlabel site1\group1\past1_1 "Past";
make site1\group1\pres1_1;
setlabel site1\group1\pres1_1 "Present";
make site1\group1\fut1_1;
setlabel site1\group1\fut1_1 "Future";
/* Group 2 */
make site1\group2;
setlabel site1\group2 "Group 2";
make site1\group2\past1_2;
setlabel site1\group2\past1_2 "Past";
make site1\group2\pres1_2;
setlabel site1\group2\pres1_2 "Present";
make site1\group2\fut1_2;
setlabel site1\group2\fut1_2 "Future";
/* Site 2 */
make site2;
setlabel site2 "Site: 2";
/* Group 3 */
make site2\group1;
setlabel site2\group1 "Group 3";
make site2\group1\past2_1;
setlabel site2\group1\past2_1 "Past";
make site2\group1\pres2_1;
setlabel site2\group1\pres2_1 "Present";
make site2\group1\fut2_1;
setlabel site2\group1\fut2_1 "Future";
/* Copy output objects after the tree exists */
copy \work.overview1\Print#1\Print#1 to site1;
copy \work.past1_1\Print#1\Print#1 to site1\group1\past1_1;
copy \work.pres1_1\Print#1\Print#1 to site1\group1\pres1_1;
copy \work.fut1_1\Print#1\Print#1 to site1\group1\fut1_1;
copy \work.past1_2\Print#1\Print#1 to site1\group2\past1_2;
copy \work.pres1_2\Print#1\Print#1 to site1\group2\pres1_2;
copy \work.fut1_2\Print#1\Print#1 to site1\group2\fut1_2;
copy \work.past2_1\Print#1\Print#1 to site2\group1\past2_1;
copy \work.pres2_1\Print#1\Print#1 to site2\group1\pres2_1;
copy \work.fut2_1\Print#1\Print#1 to site2\group1\fut2_1;
run;
ods document close;
It didn't actually run the code (because no test data to create the objects), so definitely could be wrong!
I have found a/the solution, I will post it tomorrow when I have my works laptop open again.
Thanks, I did try to put just the overview at the end but in the replayed document it was also at the end, may if I put all the copy statements at the end it would work, but I would need to call the the dataset I am using to drive the call executes twice.
Out of interest, which AI did you use? The AI on Google search was terrible and kept giving me code that did not even run.
Glad you found a solution. Curious if you try the AI's code if it will work (even if not optimal for your call execute solution).
I'm using GitHub Copilot in VS code with the SAS Extension. GitHub Copilot automatically picks an LLM. Looks like it used GPT-5.4 mini for my questions.
When I have test data, it will actually write a program, then ask if it can batch submit it. If I say yes, it will run the program, then check the log for errors, and iterate until it gets fixed. Crazy stuff!
To make this a little simpler,
Of the three code samples below the first two worked fine, but when I tried to combine them in the third it threw an error that it could not find \site1\group1
PROC DOCUMENT name=work.a(write);
/* Site 1 */
MAKE site1;
SETLABEL site1 "Site: 1";
/* Group 1 */
MAKE site1\group1;
SETLABEL site1\group1 "Group 1";
MAKE site1\group1\past1_1;
COPY \work.past1_1\Print#1\Print#1 to site1\group1\past1_1;
SETLABEL site1\group1\past1_1 "Past";
RUN;
ODS document close;
PROC DOCUMENT name=work.b(write);
/* Site 1 */
MAKE site1;
COPY \work.overview1\Print#1\Print#1 to site1;
SETLABEL site1 "Site: 1";
RUN;
ODS document close;
PROC DOCUMENT name=work.c(write);
/* Site 1 */
MAKE site1;
COPY \work.overview1\Print#1\Print#1 to site1;
SETLABEL site1 "Site: 1";
/* Group 1 */
MAKE site1\group1;
SETLABEL site1\group1 "Group 1";
MAKE site1\group1\past1_1;
COPY \work.past1_1\Print#1\Print#1 to site1\group1\past1_1;
SETLABEL site1\group1\past1_1 "Past";
RUN;
ODS document close;
Eventually I managed to get Gemini (not the best idea for coding) to give me a working solution by using some DIR commands at the top level.
PROC DOCUMENT name=work.c(write);
/* Site 1 */
MAKE site1;
SETLABEL site1 "Site: 1";
DIR site1;
COPY \work.overview1\Print#1\Print#1 to ^;
DIR ^^;
/* Group 1 */
MAKE site1\group1;
SETLABEL site1\group1 "Group 1";
MAKE site1\group1\past1_1;
COPY \work.past1_1\Print#1\Print#1 to site1\group1\past1_1;
SETLABEL site1\group1\past1_1 "Past";
RUN;
ODS document close;
Still not sure why exactly it did not work, I am assuming something to do with it being the top level. Will try and investigate further when I get a chance with a different AI model.
Nearly 200 sessions are now available on demand in the Innovate Hub.
Watch Now →Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.