cancel
Showing results for 
Search instead for 
Did you mean: 

Inserting the internal report revision number in the printout

anders_gustafsson
Participant
0 Kudos

There is a convoluted way of doing so, described here: http://www.tek-tips.com/viewthread.cfm?qid=659152

I would like an easier way though. Enhancement request?? Or is it available programmatically so I could encapsulate in an user-defined DLL?

Why do I want this? Well it is terribly useful for troubleshooting to be able to see if a printout was created by an outdated rpt.

Message was edited by: Don Williams

Accepted Solutions (1)

Accepted Solutions (1)

former_member183750
Active Contributor
0 Kudos

So, I'm not sure about what was suggested there. But see this KBA:

1392793 - How to retrieve Crystal report version information using Visual Studio .NET?


- Ludek

Senior Support Engineer AGS Product Support, Global Support Center Canada

Follow us on Twitter

Message was edited by: Don Williams

anders_gustafsson
Participant
0 Kudos

Sorry. I managed to mangle the link pasting. Please remove the extraneous HTTP://

But basically the article describes a way whereby you create a subreport against the file system, filter on your report, and list the internal version as it is accessible as a variable this way.

I tested it and it works, but I do not know how much overhead it adds..

So, to get this we need to use the Inproc RAS API, which means we need to enter an OEM agreement with SAP? What does that cost and who do we contact? Does a mail to technologypartner@businessobjects.com suffice?

0 Kudos

Hi Anders,

I fixed your link...

No need to be an OEM for an Enhancement request.

See the MS MSDN help file on that property:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa380376(v=vs.85).aspx

UFL would be the easiest way to implement this yourself.

Don

Answers (1)

Answers (1)

0 Kudos

Hi Anders,

It would be an Enhancement request so add it to Idea Place.

That number is saved as part of the files system and a property of the file. Basic Windows file functionality.

Don

PS - link doesn't work in IE, had to use Firefox...

anders_gustafsson
Participant
0 Kudos

Well. I have located it in the file. The info is stored as records with 0x1E in between. The actual strings are stored preceeded by a byte that is the string length + 1.

Not sure what you mean by "That number is saved as part of the files system and a property of the file" that would inply that it would be visible if you hit properties on the file, but it is not.

I have always had the impression that Windows is oblivious of the CR version number. The windows installer cannot read it for instance.

Edit: OK. Now I see the picture... But I do not see that info. How did you get that dialog?

Edit:2 I guess you mean propwerty sets of storage files? Let me dig into that..

anders_gustafsson
Participant
0 Kudos

OK. Basically this, need to put into an UFL, but how do you read the name of the file from an UFL or do you simply call it with the name and grab that from the predefined parameters?

// Reads the internal CR Revision number from File into Return

void CCRRevision::GetRevision(CString File, CString &Return)

{

  // http://msdn.microsoft.com/en-us/library/windows/desktop/aa379016(v=vs.85).aspx

  // http://msdn.microsoft.com/en-us/library/windows/desktop/aa380376(v=vs.85).aspx

  // http://forums.asp.net/t/966345.aspx?Problem+with+C+Class

  HRESULT hr = S_OK;

  IPropertySetStorage* pPropSetStg = 0;

  IPropertyStorage* pPropStg = NULL;

    // Open the root storage.

  try

  {

  StgOpenStorageEx(File, STGM_READ | STGM_SHARE_DENY_WRITE, STGFMT_ANY,0, NULL, NULL, __uuidof(pPropSetStg), (void**)&pPropSetStg);

  if (pPropSetStg == NULL) return;

  pPropSetStg->Open(FMTID_SummaryInformation, STGM_READ | STGM_SHARE_EXCLUSIVE, &pPropStg);

  // Read property using the ReadMultiple. This method takes a PROPVARIANT which is an extension of VARIANT.

  PROPVARIANT pvar;

  PROPSPEC propspec;

  // Indicate that we want to access the property by ID rather than through its name

  propspec.ulKind = 1;

  PropVariantInit(&pvar);

  propspec.propid = PIDSI_REVNUMBER;

  pPropStg->ReadMultiple(1, &propspec, &pvar);

  // For decisions and revisions which a minute will reverse.

  Return = pvar.pszVal;

  PropVariantClear(&pvar);

  }

  catch(...)

  {

  }

  if (pPropStg != 0) pPropStg->Release();

  if (pPropSetStg != 0) pPropSetStg->Release();

  return;

}

anders_gustafsson
Participant
0 Kudos

OK. UFL done. You need to open differently:

hr = StgOpenStorageEx(wcstring, STGM_DIRECT_SWMR | STGM_READ | STGM_SHARE_DENY_NONE, STGFMT_ANY,0, NULL, NULL, ProviderGuid, (void**)&pPropSetStg);

As the file is already opened, also, the resulting DLL is kind of large (7M compared to my others that are around 20k) as it needs to duplicate all the COM stuff that already exists in CR. It works well though. Just add a variable with a formula of "CRRevision (Filename)" to have the internal versionnumber visible.

Still wish this was a standard function though.

0 Kudos

Hi Anders,

You have been busy....

I heard back from the Product/Dev Owner last night and he's sent the request off to a Developer to look into adding it in the list of Special functions, where all of the other info from that TAB is.

One question, in CR Designer it auto increments when the report is saved. So in the SDK you'll be able to get the value also. Would you like to be able to increment the value also, it should not be able to decrement or set it to any value, increment only? Or simply leave it up to the engine to do this when ONLY using the SaveAs() API?

It may only be we can add the API as a read only property, which is the easiest to do. So depending on the work load that may be all we get but we can put it on the wish list for the SaveAs() increment.

Thanks again

Don


anders_gustafsson
Participant
0 Kudos

Let me explain why I dug into this... It has actually been in the back of my head for a long time, pretty much for the same reasons, but the "trigger" in this case was a case when the printed payslips were OK, but the emailed ones had incorrect info. They are all created from the same .rpt and the same code. Eventually, the user (everything would be so much easier without users..) felt it appropriate to tell me (finally) that they were created on two different PCs...

I checked and .rpt file on both and found that the incorrect one had a later modify date than the correct file, but an internal version that was some 40 increments behind the correct file.

Had I had this info on the actual printout, in 6pt text, vertically aligned to the left margin. The difference would have been immediately noticed. The error was a bug in a formula in a subreport.

So, for me, the Revision number as a read-only property would work perfectly.

0 Kudos

Hi Anders,

It's done and will be in SP 13.

KBA - 2101359 - ER - RevisionNumber and LastSavedBy added to CR for VS .NET SDK

Only available through the .NET SDK for now.

Thanks again

Don


anders_gustafsson
Participant
0 Kudos

Thanks! Have a link? I tried searching for 2101359 but found no hits.

former_member183750
Active Contributor
0 Kudos

Hi Anders

The KBAs take 48+ hours to replicate from the time of creation (just an FYI on the process we all have to put up with ). Anyhow, the KBA was replicated over the weekend and the link is the usual million miles long URL for KBAs.

- Ludek

anders_gustafsson
Participant
0 Kudos

Perfect! So I should download SP3 of the runtime and try it? Nothing else needed?

former_member183750
Active Contributor
0 Kudos

You mean SP 13?

(ETA: Jan / Feb 2015)

- Ludek

0 Kudos

KBA should be available now. It has the code you need to add to your app.

To add it to your report you could insert a text box and put the value into it using RAS or you could right a UFL to get the number using the SDK and insert that into a formula.

It will require distributing the .NET SDK SP13 though...

Thanks again

Don

DellSC
Active Contributor
0 Kudos

Instead of using RAS, you could make it a parameter to the report, place the param on the report where you want the version number to display, and have your code set the value of the parameter before running the report.

-Dell

0 Kudos

Actually the API is available in both RAS and the Engine.

Don

anders_gustafsson
Participant
0 Kudos

Yes. I meant SP13.Sorry I was confused since there has been a flurry of releases lately CR 13 SP13 it is and I can wait until february.In that case I will go for the suggestion Dell S-C suggested. Push it to the report as a parameter.

anders_gustafsson
Participant
0 Kudos

OK. I downloaded SP14 (32 bit msi) and installed on my development machine. It still flags m_Report->SummaryInfo->RevisionNumber; as invalid, claiming that SummaryInfo has no such member. I tried specifying either:

#using <CrystalDecisions.CrystalReports.Engine.dll>

or

#using <C:\Windows\assembly\GAC_MSIL\CrystalDecisions.CrystalReports.Engine\13.0.2000.0__692fbea5521e1304\CrystalDecisions.CrystalReports.Engine.dll>

Is there anything else I need to do?

edit:

OK. It still references the old dll, but why Xi? I never installed Xi on this machine...

Assembly crystaldecisions.crystalreports.engine

    Member of Custom Component Set

    c:\program files (x86)\sap businessobjects\crystal reports for .net framework 4.0\common\sap businessobjects enterprise xi 4.0\win32_x86\dotnet\crystaldecisions.crystalreports.engine.dll

Edit: Uninstalled everything but the full SAP Crystal Reports 2013 that I have, reinstelled CRVS runtime. I still have to have this ugly #uses:

#using <C:\Windows\assembly\GAC_MSIL\CrystalDecisions.Shared\13.0.2000.0__692fbea5521e1304\CrystalDecisions.Shared.dll>

#using <C:\Windows\assembly\GAC_MSIL\CrystalDecisions.Windows.Forms\13.0.2000.0__692fbea5521e1304\CrystalDecisions.Windows.Forms.dll>

#using <C:\Windows\assembly\GAC_MSIL\CrystalDecisions.CrystalReports.Engine\13.0.2000.0__692fbea5521e1304\CrystalDecisions.CrystalReports.Engine.dll>

0 Kudos

Wrong, Do not install the runtime on your DEV PC. Uninstall it and use the first link to integrate into VS, when adding CR assemblies do not use the Browse button, use the .NET tab when adding assemblies. Runtime and CR for VS installer will not update each other and will overwrite the runtime so you may be mixing versions.

All you should see in the of what is installed on your DEV PC is this ( note I am using a beta of SP 15 😞

Download my test app for printing in KBA 2133438 and run it. It also uses the same API's to get the history.

See if that works after cleaning up your DEV PC runtimes.

Don

anders_gustafsson
Participant
0 Kudos

OK. Apparently did I misread the docs. I have followed yor advice, but cannot find KBA 2133438?

This is what I have now:

I took out the annoying paths so that the code again reads:

#using <CrystalDecisions.Shared.dll>

#using <CrystalDecisions.Windows.Forms.dll>

#using <CrystalDecisions.CrystalReports.Engine.dll>

Cleaned the app and rebuilt it. App runs fine! Thanks! Can you please clarify what you mean by: "when adding CR assemblies do not use the Browse button, use the .NET tab when adding assemblies." I did neither (this is an C++ MFC app)

0 Kudos

Doh, sorry Anders, typo, KBA is 2163438. I only missed by one key...

In VS when adding assemblies use the .NET tab and do not browse to the CR runtime files. .NET Tab loads them from the GAC:

To update you DEV PC us the first link on this page:

All others are for redist purposes ONLY. Do not install any of the Redist packages on your DEV PC. The installer will ask you if you want the 64 bit runtime, that is the only option.

Don

anders_gustafsson
Participant
0 Kudos

OK. Thanks. I have printed out the tutorial, seems like excellent stuff.

FWIW, I use VS 2012 and C++/MFC (Only printing is .NET), the operation to add references is sligthtly different from C#. I will include a screenshot in case it helps someone else. Also, it does not seem necessary to add references here, just adding #using to the code seems to be sufficient.

My app works just fine now. I would love to test your sample app, but I cannot find it. The page says: "NOTE: To run just the executable browse to this folder: \RAS2010_Printing\bin\Release and double click on RAS10_CSharp_Printers.exe" - Am I to assume that the "Installer into vs" installs it? I did search on my machine, but could not find it. I also opened up the installer archive, but could not find it. Just in case someone else needs it....

Also, DOC-7824 seems to have two links pointing to the same document. The headings "Basics" and "The basics" both point to DOC-57979.

Just nitpicks I greatly applaud your work putting this together.

0 Kudos

Hi Anders,

Ah yes, good to know you are using C++. You have download the sample app attached to the KBA. It the last thing in the KBA:

Attachments

File Name

File Size (KB)

Mime Type

RAS2010_Printing.zip

684

application/x-zip-compressed

Don

anders_gustafsson
Participant
0 Kudos

Thanks! Well, that was.... comprehensive! I will have to take a peek at the source to see how you do the runtime version check. I was told many moons ago that it was not possible. But I see that you iterate over the assemblies. There is no call to get the version from cr.

0 Kudos

Correct, All of our installers always adds the engine so it's safe to go get it for version number. I also used the Appdomain and there are other ways to get them.

Thanks again

Don