Delphi TFloatField.DisplayFormat for numeric fields less than 1.0 - database

This is my procedure.
procedure format_integer_field(Atable: TDataSet);
var i: integer;
begin
if Atable.Active then
if Atable.FieldCount > 0 then
with Atable do
begin
for i:= 0 to FieldCount-1 do
if (Fields[i] is TIntegerField) then
begin
(Fields[i] as TIntegerField).DisplayFormat := '###,###';
(Fields[i] as TIntegerField).EditFormat := '#';
end
else
if (Fields[i] is TFloatField) then
begin
(Fields[i] as TFloatField).DisplayFormat := '###,###.##';
(Fields[i] as TFloatField).EditFormat := '#.##';
end;
end;
end;
This is work fine until a number like "0.9" has been entered and result will be ".9".
How can I have thousand separator and zero before floating point that smaller than "1".

Try (Fields[i] as TFloatField).DisplayFormat := '##0,000.00';
As you did read in documentation at http://docwiki.embarcadero.com/RADStudio/XE3/en/Using_Default_Formatting_for_Numeric,_Date,_and_Time_Fields it says
Default formatting is performed by the following routines:
FormatFloat -- TFloatField, TCurrencyField
And how you did read in the following documentation pages
http://docwiki.embarcadero.com/Libraries/XE3/en/System.SysUtils.FormatFloat
http://docwiki.embarcadero.com/Libraries/XE3/en/Data.DB.TNumericField.DisplayFormat
the documentation quotes
0 -> Digit placeholder. If the value being formatted has a digit in the position where '0' appears in the format string, then
that digit is copied to the output string. Otherwise, a '0' is
stored in that position in the output string.
# -> Digit placeholder. If the value being formatted has a digit in the position where '#' appears in the format string, then
that digit is copied to the output string. Otherwise, nothing is
stored in that position in the output string.
So by using "#" in the formatting pattern you tell Delphi "i do not need any digits (and thousands separators with them) in this place, but you might put them if you want" - and since Delphi does not want to put leading zeros - you don't have any. However, if you really need those digits and the thousands separator with them, you put "0" instead of "#" and that way you tell Delphi "the digits just need to be here, whether you want to put them or not"

The format you need is ###,##0.0#

Related

How to extract substring from string in crystal report

I am new to crystal reports.
My data(employee ids) is of the following format
Abc123, uttd333, ddt-435
I want to extract only numbers and remove leading letters and special characters.
Also there are certain values that should never be printed.
Admin Ids such as
Gree999, ttt999
I know there is a mid function but that requires me to specify the position from where the substring should begin. These values don't have a fixed number of leading letters.
Is there anything like Ltrim like we have in SQL that we can use to achieve this in crystal reports?
Afaik there's no built-in function in CR to remove non-numeric characters from a string, so you'll have to roll your own (replace {Befehl.EmployeeId} with your field):
StringVar employeeId := {Befehl.EmployeeId};
StringVar result := "";
NumberVar i;
// transfer numeric chars into result one by one
For i := 1 To Length(employeeId) Do
(
If IsNumeric(employeeId[i]) Then
result := result + employeeId[i];
);
// output result only if employeeId is not in your admin list
If employeeId In Split('Gree999,ttt999', ',') Then
'--Admin--'
Else
result;
Here's an alternative approach to grabbing just the numeric portion of the string:
strReverse(ToText(Val(strReverse({EmpId})),0,""))
It takes advantage of knowing that the digits are always at the end.
To handle trailing zeros, you can use:
local stringvar withoutTrailingZeros := strReverse(ToText(Val(strReverse({EmpId})),0,""));
withoutTrailingZeros + ReplicateString("0", Len({EmpId}) - (instr({EmpId}, withoutTrailingZeros) + Len(withoutTrailingZeros) - 1))
But mweber's answer above is simpler now.

Combobox value to code

I'm a Pascal newbie and I already read some stuff about it, but it is still pretty hard for me. I want to create a simple password generator, and adjust the number of characters.
I found a function that actually generates the random password for me, which is this:
function RandomPassword(PLen: Integer): string;
var
str: string;
begin
Randomize;
//string with all possible chars
str := 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
Result := '';
repeat
Result := Result + str[Random(Length(str)) + 1];
until (Length(Result) = PLen)
end;
This is the code that prints the string to the Memo:
procedure TForm1.Button2Click(Sender: TObject);
begin
Memo1.Caption := RandomPassword(10);
end;
I also got a TComboBox, and I want to use the value from the combobox to chose the number of characters (6-32). The number of characters is in this case 10 but I want to use the value from the Combobox instead of a predetermined number. Who can help me? I'd appreciate it!
You can select the combobox value like this:
RandomPassword(StrToInt(ComboBox.Items[ComboBox.ItemIndex]))
ComboBox.ItemIndex returns the index of select combobox item
ComboBox.Items[] is used to select a item in the combobox.
StrToInt() is used cause the combobox value is a string and you have to change it to integer

Including single quote in data while inserting to database

I have a string "I love McDonald's burgers. it's the best."
and I would like to insert it into a column breaking them into 15 character strings.
Hence I need the result as string inserted in 3 rows
I love McDonald
's burgers. it'
s the best.
But if I use ' ' to include the ', an extra ' is present in the string which will affect my calculation of 15 character breakage.
Is there any other way to include ' without having to use one more ' to escape it?
Please help.
You don't need to add an extra ' if you're breaking the string into a variable:
DECLARE
mcdonald_string VARCHAR2(50) := 'I love McDonald''s burgers. it''s the best.';
BEGIN
WHILE LENGTH(mcdonald_string) > 0 LOOP
INSERT INTO your_table(your_field) VALUES (SUBSTR(mcdonald_string,1,15));
mcdonald_string := SUBSTR(mcdonald_string,16);
END LOOP;
COMMIT;
END;
Doubling the quotation marks within a complicated literal,
particularly one that represents a SQL statement, can be tricky. You
can also use the following notation to define your own delimiter
characters for the literal. You choose a character that is not present
in the string, and then do not need to escape other single quotation
marks inside the literal:
-- q'!...!' notation allows the of use single quotes
-- inside the literal
string_var := q'!I'm a string, you're a string.!';
http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/fundamentals.htm#sthref339

Reading different data on a single line from file in VHDL

Supposing I've got a file filled with data separated by a tabulation (in this format):
1 2
3 4
5 6
and I'd like to read these data in pairs from a single line, so that result would be as follows:
var1=1;
var2=2;
var1=3;
var2=4;
var1=5;
var2=6;
How am I supposed to work? Right now my code works for a single data on a single line (see following):
read_from_file: process(clk)
variable input_data: natural;
variable ILine: line;
begin
for i in 0 to NSAMPLES-1 loop
readline (input_vectors, ILine);
read(ILine, input_data);
end loop;
end process;
Thank you for helping!
You should be able to call the read function again.
For example:
read_from_file: process(clk)
variable input_data_column1: natural;
variable input_data_column2: natural;
variable ILine: line;
begin
for i in 0 to NSAMPLES-1 loop
readline (input_vectors, ILine);
read(ILine, input_data_column1);
read(ILine, input_data_column2);
-- Now you can do things like conv_std_logic_vector(input_data_column1, bitwidth) etc
end loop;
end process;
Note: I am not positive if any whitespace will be accepted. Spaces have worked for me.

Move SQL Server Unicode XML column to Oracle via Base64 document

Problem:
When I decode and reconstitute my base64 encoded XML document, I get null values between each character. I think I need to convert to NCHAR, but it's not working as expected.
Block : PgA8AC8AYwBsAGkAbgBpAGMAYQBsAF8AcwB0AHUAZAB5AD4A
Decode : 3E003C002F0063006C0069006E006900630061006C005F00730074007500640079003E00
Varchar2: > < / c l i n i c a l _ s t u d y
Raw2NHex: 3E003C002F0063006C0069006E006900630061006C005F00730074007500640079003E00
(Note: The blank characters on the Varchar2 output are actually nulls.
Background:
I am having difficulty reading an XML data column from a base64 encoded element in an XML document that I build in SQL Server.
Basically, we are moving an XML document from one system to another, and had to use Base64 because Unicode < characters that were not < tag characters were being translated as <. Namely the text said < 3 months, using the unicode less than sign.
So, we translated the xml document into Base64 which worked great.
Sample XML Document
My Oracle decode function is this
v_clob := '';
v_offset := 1;
FOR i IN 1 .. ceil(dbms_lob.getlength(p_clob_in) / v_buffer_size) LOOP
--
-- Substr is 1-relative.
--
dbms_lob.read(p_clob_in, v_buffer_size, v_offset, v_buffer_base64);
--
IF v_buffer_base64 IS NULL THEN
EXIT;
END IF;
DBMS_OUTPUT.PUT_LINE('Block : ' || SUBSTR(v_buffer_base64, 1, 80));
--
-- Decode the Base64 into a RAW string
-- ... This works as expected
--
v_buffer_decode := utl_encode.base64_decode(utl_raw.cast_to_raw(v_buffer_base64));
DBMS_OUTPUT.PUT_LINE('Decode : ' || v_buffer_decode);
--
-- Cast the RAW output into VARCHAR2
-- ... This results in null characters between each character
--
v_buffer_varchar2 := utl_raw.cast_to_varchar2(v_buffer_decode);
DBMS_OUTPUT.PUT_LINE('Varchar2: ' || v_buffer_varchar2);
--
-- Convert the decoded RAW string into NVARCHAR
-- ... This doesn't actually do anything, it just puts out the same RAW characters.
-- ... I get the same result as I do with RAWTONHEX.
--
SELECT CAST(v_buffer_decode as NVARCHAR2(1024))
INTO v_buffer_nvarchar2
FROM dual;
DBMS_OUTPUT.PUT_LINE('CastNVC : ' || v_buffer_nvarchar2);
v_clob := v_clob || v_buffer_nhex;
--
v_offset := v_offset + v_buffer_size;
--
END LOOP;
What I need is something that can take the 2-byte NCHAR and represent it as the proper single NCHAR value in the NVARCHAR2 variable.
After struggling with this and reviewing the debug statements, I came to the realization that Microsoft and Oracle treat the high order byte of wide character sets differently.
In Microsoft, the binary is rendered as 3E00. However, if you use
select '*' || utl_raw.cast_to_nvarchar2('3e00') || '*' from dual
You get *γΈ€*. If, however, you do
select '*' || utl_raw.cast_to_nvarchar2('003e') || '*' from dual
You get *>*. Which is the proper conversion.
So, what I had to do was to extract characters from the decoded RAW string and flip the low-order and high-order bytes so that 3E00 became 003E. I also, in the end, had to skip the FFFE base64 prefix from the binary data since Oracle didn't throw it away.
Here is the final code.
FUNCTION decode_base64(p_clob_in IN CLOB) RETURN CLOB IS
--
v_clob clob;
v_result clob;
v_offset number;
v_buffer_size binary_integer := 48;
v_buffer_base64 varchar2(1024);
v_buffer_decode RAW(1024);
v_buffer_varchar2 VARCHAR2(1024);
v_buffer_nhex nvarchar2(1024);
v_buffer_nvarchar2 nvarchar2(1024);
v_buffer_nchar NVARCHAR2(4);
v_buffer_convert RAW(4);
--
BEGIN
--
IF p_clob_in IS NULL THEN
RETURN NULL;
END IF;
--
dbms_lob.createtemporary(v_clob, true);
--
v_clob := '';
v_offset := 1;
FOR i IN 1 .. ceil(dbms_lob.getlength(p_clob_in) / v_buffer_size) LOOP
--
-- Substr is 1-relative.
--
dbms_lob.read(p_clob_in, v_buffer_size, v_offset, v_buffer_base64);
--
IF v_buffer_base64 IS NULL THEN
EXIT;
END IF;
--
-- Decode the Base64 into a RAW string
--
v_buffer_decode := utl_encode.base64_decode(utl_raw.cast_to_raw(v_buffer_base64));
--
-- Convert the decoded text into NVARCHAR2 characters
-- Note: Microsoft and Oracle disagree on high byte first or second
-- Take out each character (4 characters) and flip the 3rd and 4th hex character to the front
-- Thus, 3E00 becomes 003E
-- Note: We have to ignore Microsoft's Base64 prefix code of FFFE. (FEFF when extracted :) ).
--
v_buffer_nvarchar2 := '';
FOR J IN 1 .. ceil(LENGTH(v_buffer_decode) / 4) LOOP
--
v_buffer_convert := SUBSTR(v_buffer_decode, (J - 1) * 4 + 3, 2) || SUBSTR(v_buffer_decode, (J - 1) * 4 + 1, 2);
IF v_buffer_convert <> 'FEFF' THEN
v_buffer_nchar := utl_raw.cast_to_nvarchar2(v_buffer_convert);
v_buffer_nvarchar2 := v_buffer_nvarchar2 || v_buffer_nchar;
END IF;
--
END LOOP;
v_clob := v_clob || v_buffer_nvarchar2;
--
v_offset := v_offset + v_buffer_size;
--
END LOOP;
--
v_result := v_clob;
dbms_lob.freetemporary(v_clob);
RETURN v_result;
--
END decode_base64;
That was the fix.

Resources