Change PDF out put file name dynamically in oracle reports - oracle

Please guide how to change output PDF file name at run time
I am using below code in after parameter form trigger but its not working :
:DESNAME := 'INVOICE_'||:P_CLIENT||'.PDF';
Please guide me..

You didn't mention which Reports version you use; up to 6i program that is used to create reports was called "Reports Builder", while later versions use name "Reports Developer". Doesn't really matter, but - if you open Reports Online Help System (navigate to "Help" menu) and search for DESNAME, you'll find which executables can be used to set DESNAME's value. RWBUILDER is not among them. And yes, rwbuilder is Builder's and/or Developer's EXE name.
It means that you're out of luck, at least regarding the way you're trying to set DESNAME's value. You can't set it in any of Reports' triggers. I mean, you can, but it won't take any effect.
However, if you call the report from, for example, a form developed by Oracle Forms, then you'd use RWRUN which can specify DESNAME value and yes, you can dynamically create it.
For some more info, do read Help I pointed you to previously.

Among several ways of calling Reports from Forms, i can suggest you to use adding RP2RRO.pll to your Form :
And then, add parameters related to this pll :
And you may call your reports by this code :
Pr_Print_Rp2Rro('Rep_Invoice','|Prm1|Prm2|','|'||:Prm1||'|'||:Prm2||'|','no','INVOICE_'||:P_Client||'.PDF');
assuming you have two user defined parameters namely : Prm1 & Prm2. And Pr_Print_Rp2Rro is a procedure with the following code :
Procedure Pr_Print_Rp2Rro(
i_rep_name varchar2,
i_prm_name varchar2,
i_prm_val varchar2,
i_param_frm varchar2, -- 'Yes','No'
i_desname varchar2,
i_destype varchar2 default 'FILE'
) Is
plist ParamList;
arr_prm_name owa.vc_arr;
arr_prm_val owa.vc_arr;
Begin
plist := Get_Parameter_List('REPPARAM');
if not Id_Null(plist) then
Destroy_Parameter_List('REPPARAM');
end if;
plist := Create_Parameter_List('REPPARAM');
Add_Parameter(plist, 'PARAMFORM', Text_Parameter, i_param_frm);
Rp2rro.SetDestype(i_destype);
Rp2rro.SetDesname(i_desname);
for i in 1..100
loop
arr_prm_name(i) := substr(i_prm_name,instr(i_prm_name,'|',1,i)+1,instr(i_prm_name,'|',1,1+i)-instr(i_prm_name,'|',1,i)-1);
arr_prm_val(i) := substr(i_prm_val,instr(i_prm_val,'|',1,i)+1,instr(i_prm_val,'|',1,1+i)-instr(i_prm_val,'|',1,i)-1);
if length(arr_prm_name(i)) > 0 then
Add_Parameter( plist, arr_prm_name(i) , Text_Parameter, arr_prm_val(i) );
end if;
end loop;
Rp2rro.Rp2rro_Run_Product(Reports, i_rep_name, Synchronous, Runtime,Filesystem, plist,null);
End ;
As you may have noticed this procedure contains a method Rp2rro.SetDesname(i_desname) which you could use and manage your task to create Report names spesific to your customer, unless you set your Destype parameter as CACHE.

Related

How do I save a picture from a open picture dialogue to a file

Hi I'm currently using Delphi 2010.
I basically have a form where a user has to enter information about themselves and upload a picture. I have an Image component on my form. I did some research and many of the websites I looked at said to use a OpenPictureDialogue to allow the user to select an image and display it in the Image component.
My question is, how can I save this image to a file on my computer? Keeping in mind I will have multiple users adding their picture and that I will have to use the picture later on again, basically I want to use the LoadFromFile procedure to display the picture in my program later on.
I also read many websites saying to use the SavePictureDialogue, but that allows the user to select the file they want the image to be saved to and I don't want that, I want it to save to a file that only I can access.
I have this so far, I know it is very limited.
if opdAcc.Execute then
begin
if opdAcc.FileName <> '' then
begin
imgAccImage.Picture.LoadFromFile(opdAcc.FileName);
end;
end;
I am a student and my knowledge is quite limited and I would appreciate any help. :)
First of all, there is no place on the hard drive that only you can access. But you can create a folder to store your files and copy users' pictures there. This reduces the likelihood that the user will have access to these files. The usual folder for storing such files is the AppData folder. It is better to create a folder with the same name as your application in AppData and store such files there.
Suppose the GetPicturesDirectoryPath function generates the address of such a folder and ensures that this folder has already been created or will be created. The next step is to generate a unique name for the file you want to store. Note that multiple users may select files with the same name. In this case, after copying the picture selected by the second user, the image file will be written over the previous user's file. If a unique identifier is assigned to each user, this identifier is the best choice for the picture file name. But you can use the GetGUIDFileName function to create a unique address. Make sure the generated address is kept with the rest of the user information, or the connection between the copied file and the user will be lost. The implementation of all these will be something like the following:
uses IOUtils;
function GetAppDataDirectoryPath: string;
begin
...
end;
function GetPicturesDirectoryPath: string;
begin
Result := TPath.Combine(GetAppDataDirectoryPath, 'MyApp');
TDirectory.CreateDirectory(Result);
end;
function GetUniqueFilePath(const Extension: string): string;
begin
Result := TPath.ChangeExtension(
TPath.Combine(GetPicturesDirectoryPath, TPath.GetGUIDFileName),
Extension);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
DestPath: string;
begin
OpenPictureDialog1.Options := OpenPictureDialog1.Options +
[ofFileMustExist]; // make sure that selected file exists
if OpenPictureDialog1.Execute then
begin
DestPath := GetUniqueFilePath(TPath.GetExtension(OpenPictureDialog1.FileName));
TFile.Copy(OpenPictureDialog1.FileName, DestPath);
if TFile.Exists(DestPath) then
Image1.Picture.LoadFromFile(DestPath)
else
ShowMessage('Well, something went wrong!');
end;
end;
Read this to implement GetAppDataDirectoryPath.

select more than one checkbox to execute condition

I want a text file to show contents in memo1 once I have selected 2 checkboxes.
How would I do this?
I tried the code below but I can't seem to get it right.
if CheckBox1.Checked and CheckBox2.Checked then
begin
memo1.lines.LoadFromFile('files\RS.txt');
end;
I also want to be able to select the checkboxes individually Like:
(pointing this out in case combining them prevents checking them individually)
Checkbox1:
procedure TForm1.CheckBox1Change(Sender: TObject);
begin
memo1.lines.LoadFromFile('files\R.txt');
end;
Checkbox2:
procedure TForm1.CheckBox2Change(Sender: TObject);
begin
memo1.lines.LoadFromFile('files\S.txt');
end;
Any suggestions/Improvements will be appreciated.
Running Lazarus IDE v1.6.4
Windows 10 x64
I'm assuming your objective is to generate a filename which depends on the
particular combination of the boolean states of the two checkboxes -
see example code below. The point of doing this is that it helps separate
the definition of what you want the file name to be from what you want to do
with it.
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Lines.LoadFromFile(GetFileName);
end;
function TForm1.GetFileName: String;
begin
// Return empty string if neither checkbox is checked
Result := '';
if Checkbox1.Checked and Checkbox2.Checked then
Result := 'files\RS.txt'
else // if we reach here only one of the checkboxes, or neither, is checked
if Checkbox1.Checked then
Result := 'files\R.txt'
else
if Checkbox2.Checked then
Result := 'files\S.txt'
end;
I've assigned an empty string to the Result of the function at the outset to ensure that the Result is always defined.
Important You'll notice that the above does not use the Change events of the Checkboxes. The reason is that you may not get the result you need (or are expecting) if the Change events are never triggered - for example if one CheckBox is set to Checked in the IDE but the other isn't, and you want to get the right file name regardless of whether the user has actually clicked either one of them.
As far as I understood you want the following behaviour:
There are two check boxes
There is one memo field
Depending on the state of the two check boxes the text in the memo field shall change
If this understanding is correct:
I typically don't use Pascal but your problem seems to be independent of the programming language used. I would do it like this:
The two procedures TForm1.CheckBox1Change and TForm1.CheckBox2Change are called whenever the corresponding check box'es state changes.
I would write a third procedure and call this third procedure from both procedures. I would do nothing else than calling this third procedure in the other two procedures.
In the third procedure I would evaluate what to do - depending on the state of both check boxes.
A separate checkboxchange proocedure per event is automatically generated by the designer if you double click the event. However that is not a rigid decision.
If you have the initial codefragment in e.g. checkbox1change, you can simply point the onchange of checkbox2 to that existing checkbox1change by using the dropdown of the onchange of checkbox2

Testing a function in PL/SQL Developer

This is my function:
FUNCTION GET(V_IN IN NUMBER) RETURN VARCHAR2 AS
V_OUT VARCHAR2(1000);
BEGIN
function body
END;
When I right click the function and click on test, I am getting the following:
begin
-- Call the function
:result := pkg.get(V_IN => :V_IN);
end;
How do I substitute a value for this variable V_IN? I need to test it for a number, say 940.
When I try the code:
declare
r varchar2(2000);
begin
-- Call the function
r := pkg.get(940);
end;
I am getting an error:
ORA-01036: illegal variable name/number
Can you suggest various ways of calling this function?
PS:
Tool used: PL/SQL Developer Allround Automations. Version 8.0.1.1502
Oracle Database 11g Enterprise Edition
Once you've clicked on your function and clicked on Test in the context menu a Test window is brought up with the code you've shown. There are two panes in this window - the top pane shows the code which PL/SQL Developer generated to invoke the function, and the lower pane contains a list of the parameters to your function. In the lower pane of the Test window there's a list of the parameters to the function with three columns - Variable, Type, and Value. Type the value you want into the Value column in the row with your parameter's name, then click on the Start Debugger button (top left of the Test window, under the 'Test Script' tab's name), then click on the Run button (immediately to the right of the Start Debugger button).
Best of luck.
"How do I substitute a value for this variable V_IN? I "
When you run the test in PLSQL Developer the bottom pane of the test window is a property list for all the substitution variables. You define the datatype and the input values (when appropriate). Output values are available in this window after the test is run.
"ORA-01036: illegal variable name/number"
Not sure what causes this. It's probably not PLSQL Developer but a bug in your function code (which you have not posted).
I was able to run the function as follows:
declare
v varchar2(1000);
begin
select pkg.get(940) into v from dual;
dbms_output.put_line(v);
end;
Also, as per APC's comment, there is a property list(the small window appearing below the PL/SQL worksheet, having Variable, Type and Value fields). You need to enter the value which you wish to pass in the value field and click on Execute (shortcut-F8). The output will be shown and highlighted in yellow in the same property list window. Click below link to refer the screenshot:
Function Call with single parameter
I assume you are still in pl/sql "Test window", when you modified the original test code to your custom. Pl/sql sometimes is buggy. Open a new "SQL window" and try to run there with dbms_output.put_line() to see the result.

how to internationalize a delphi application [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Translate application
What is the best way to internationalize my application written in delphi xe2 ?
I've seen the stringtable resource but I'm worried because I've got the feeling that the implementation could be time consuming and laborious.
Are there other equally valid methods to do this?
Maybe not the best tool for translations, but I'm using GNU Gettext for many years.
The process is quite simple:
You run dxgettext to extract strings
You translate or give for translation the files
I personally love poEdit tool to translate and manage translation repository
Optional : You merge your translation files into the final EXE
OR you put the translation files in subdirectories and that's it !
http://dxgettext.po.dk/
Update:
1/ GNU Gettext is included in JCL/JVCL library, you just need to activate this option at startup.
2/ Gnu Gettext can translate everything in the library, as VCL, JCL/JVCL also ! It's not just limited to your code !
One option is to use the Integrated Translation Environment in Delphi:
http://docwiki.embarcadero.com/RADStudio/XE3/en/Localizing_Applications_by_Using_Translation_Manager_Overview
Here you can find two articles about this theme:
Multilingua application with GNU gettext
Multilingua application with standard method (IDE)
You can find other methods and commencial components (i have used TsiLang components -excellent library-)
A Greeting.
I don't know is this the best way of internationalize an application, but for me it worked. It's a kind of home made.
I created an xml file, which is the dictionary containing the translations, but you can use any other format, from json, to xls (maybe this is the best). Than implemented a class which read the translations from this file, and a way to register procedures in case of the language is changed runtime, which is I think a good feature.
TDictionary = class
private
fOnChanged: TSignal;
fLanguage: String;
procedure setLanguage( const Value: String );
public
procedure loadFromFile( filename: string );
function getTranslation( id: string; lang: string = '' ): string;
property language: String read fLanguage write setLanguage;
property onChanged: TSignal read fonChanged;
end;
...
function TDictionary.getTranslation( id: string; lang: string = '' ): string;
begin
if lang = '' then
lang := Language; // use the default lang.
// read the translation from the file.
end;
procedure TDictionary.setLanguage( const Value: String );
begin
fLanguage := Value;
onChanged.Execute;
end;
TSignal is a class which register methods, and if you call Execute executes all the registered methods, Maybe in xe2 you have something built in for this, in delphi7 I had to create this class myself, but it's fun to implement.
in a form's createForm:
procedure TMyClass.doTranslate( dictionary: TObject );
begin
with dictionary as TDictionary do
begin
caption := dictionary.getTranslation( 'myclass.caption' );
button.caption := dictionary.getTranslation( 'some id' );
end;
// or you can go through Controls array, and automate the assignment.
end;
procedure TMyClass.FormCreate(Sender: TObject);
begin
Dictionary.onChanged.register( doTranslate );
doTranslate( dictionary );
end;
procedure TMyClass.FormDestroy(Sender: TObject);
begin
Dictionary.onChanged.deregister( doTranslate );
end;
As you can see, this is not a working example what you can copy and paste, I just wanted to show you the idea behind. if something is not clear, comment it, and I can extend my answer.
Some notes:
I think it's important to have the translations in utf8 format.
using xls makes the localizers live easier, and your too, if they ruin your xml file (If the translator is not prof., It can happen that you get back your xml file in microsoft word format)
you can put your dictionary file into resource, and load from there.
Pros
This way you can change the language runtime
if you need another language, you just need to edit the dictionary file.
Cons
If you have many forms, it's a nightmare to connect all the labels, buttons, etc, but you can automate it in smart ways.
It slows down your app a little, but not much, if changing your app language is not happening so often.
There is a product called sisulizer, it works after you have build the executable fies I think. Haven't tried it but I've read a lot about it.
Have a look at this

Oracle SQL Developer - Help for debugging

I am trying to debug a package with in the SQL Developer. The method that i am trying to debug takes 2 parameters
PROCEDURE procedure_name (dblink IN CHAR, bDebug IN BOOLEAN DEFAULT FALSE)
When i click on "Debug" icon, it asks for inputs that i need to give to this procedure. I give
dblink:='linkname';
bDebug:=TRUE;
but when it starts debugging, I see the value of dblink as
'linkname
'
i.e. linkname, lots of spaces and then the ending quote. so when in code i try to do this
`strSrc VARCHAR(120) := 'tablename'||dblink;`
it gives me error that buffer is to small, which makes sense. but why SQL Developer is doing so? how to fix it?
I am guessing your padding is coming from how SQL Developer is defining its variable to bind with (it is probably defining it as a CHAR(4000)). For now, you should be able to get around this in your test code by putting trim() around the dblink variable:
strSrc VARCHAR(120) := 'tablename'||trim(dblink);
Note that this would normally not be needed if the procedure was passed a literal (or a correctly sized CHAR variable, a VARCHAR, etc), like the production code is probably doing.
For debugging purposes, create a wrapper procedure that accepts a VARCHAR2 parameter, then passes it to your procedure; then you debug it in SQL Developer by calling your wrapper.

Resources