Delphi export to Excel - false errors in IDE for code that compiles - excel

When coding for Excel in Delphi 10.3.3, I get false errors in the IDE for code that compiles and works just fine.
The error messages...
Undeclaired identifier 'Range' at line xxx
Undeclaired identifier 'Cells' at line xxx
...for every occurrence of the two excel variables.
Here's the complete code:
procedure tmainform.ExportToExcel;
var
xls, wb, MyRange, CompletionRow: OLEVariant;
arrData: Variant;
ColCount, CurrRow, CurrCol: Integer;
begin
ColCount:= 6;
arrData:= VarArrayCreate([1, TotOrders+1, 1, ColCount], varVariant);
for CurrCol:= 1 to ColCount do case currcol of
1: arrData[1,1]:= 'ORDER#';
2: arrData[1,2]:= 'DATE';
3: arrData[1,3]:= 'ITEM';
4: arrData[1,4]:= 'QTY';
5: arrData[1,5]:= 'COST';
6: arrData[1,6]:= 'RECEIVED?';
end;
for CurrRow:= 1 to TotOrders do begin
for CurrCol:= 1 to ColCount do begin
case currcol of
1: arrData[CurrRow+1,1]:= Orders[1].Number;
2: arrData[CurrRow+1,2]:= Orders[2].Date;
3: arrData[CurrRow+1,3]:= Orders[3].Name;
4: arrData[CurrRow+1,4]:= Orders[4].Qty;
5: arrData[CurrRow+1,5]:= Orders[5].Cost;
6: arrData[CurrRow+1,6]:= Orders[6].Received;
end;
end;
end;
xls:= CreateOLEObject('Excel.Application');
wb:= xls.Workbooks.Add;
{THIS LINE} MyRange:= wb.WorkSheets[1].Range[wb.WorkSheets[1].Cells[1, 1],wb.WorkSheets[1].Cells[TotOrders+1, ColCount]]; // THIS LINE
MyRange.Value:= arrData;
MyRange.EntireColumn.Autofit;
{THIS LINE} CompletionRow:= wb.WorkSheets[1].Range[wb.WorkSheets[1].Cells[1, 1],wb.WorkSheets[1].Cells[1, ColCount]]; // THIS LINE
CompletionRow.font.bold := true;
{THIS LINE} CompletionRow:= wb.WorkSheets[1].Range[wb.WorkSheets[1].Cells[2, 5],wb.WorkSheets[1].Cells[TotOrders+1, 5]]; // THIS LINE
CompletionRow.NumberFormat:= '$#,##0.00';
xls.Visible:= True;
xls.ActiveWindow.Activate;
end;
Global variables are:
Orders: array of ordertype;
TotOrders: integer;
Again, this code runs and works just fine, but I'd like to get rid of those fake errors always showing in the upper left.

It is a known bug in Delphi. There is nothing you can do except upgrade to version "10.4 Sydney" (or later) Reference.

Related

Puzzling "info" message regarding package body requirement using Ada?

I am experiencing a peculiar "info" message from GNAT 7.4.0 (running on an "Ubuntu 19.04" system) while in the early stages of developing a QR-code generator.
I'm using some fairly aggressive compilation switches:
gnatmake -gnata -gnateE -gnateF -gnatf -gnato -gnatv -gnatVa -gnaty -gnatwe -gnatw.e main.adb
My code does build without errors, but this info message does suggest that I'm not providing a body for the package "qr_symbol".
qr_symbol.ads
with QR_Versions; use QR_Versions;
generic
Ver : QR_Version;
package QR_Symbol is
procedure Export_As_SVG;
private
type Module_State is (
Uncommitted,
One,
Zero
);
type Module_Family is (
Uncommitted,
Finder,
Separator,
Alignment,
Timing,
Format_Spec,
Version_Spec,
Data_Codeword,
EC_Codeword,
Padding
);
type Module is
record
State : Module_State := Uncommitted;
Family : Module_Family := Uncommitted;
end record;
type Module_Matrix is array (
Positive range <>,
Positive range <>
) of Module;
end QR_Symbol;
qr_symbol.adb
with Ada.Text_IO; use Ada.Text_IO;
package body QR_Symbol is
Version : constant QR_Version := Ver; -- Ver is a formal generic parameter
Side_Length : constant Positive := 17 + (Positive (Ver) * 4);
Matrix : Module_Matrix (1 .. Side_Length, 1 .. Side_Length);
procedure Export_As_SVG is
begin
Put_Line ("in Export_As_SVG()...");
Put_Line (" Version: " & Version'Image);
Put_Line (" Side_Length: " & Side_Length'Image);
-- Matrix (1, 1).State := One;
Put_Line (" Matrix (1, 1).State: " & Matrix (1, 1).State'Image);
end Export_As_SVG;
end QR_Symbol;
And here's the info output that I do not understand...
GNAT 7.4.0
Copyright 1992-2017, Free Software Foundation, Inc.
Compiling: qr_symbol.adb
Source file time stamp: 2019-12-07 16:29:37
Compiled at: 2019-12-07 16:29:38
==============Error messages for source file: qr_symbol.ads
9. procedure Export_As_SVG;
|
>>> info: "QR_Symbol" requires body ("Export_As_SVG" requires completion)
29 lines: No errors, 1 info message
aarch64-linux-gnu-gnatbind-7 -x main.ali
aarch64-linux-gnu-gnatlink-7 main.ali
Program output (given correct input, does gives correct output)...
$ ./main '' V1
QR Version requested: V 1
in Export_As_SVG()...
Version: 1
Side_Length: 21
Matrix (1, 1).State: UNCOMMITTED
QUESTION:
Why is there an info message suggesting that I need to provide a body for this package when it is clear that I have already done so?
An info message is not used to suggest that you should change your program, only to provide some (useful or not) information. In your case, the information is true. If it weren't fulfilled, it'd turn to an error.
You may want to check if this flag is causing the generation of this message:
According to GNAT User's Guide:
-gnatw.e
`Activate every optional warning.'
This switch activates all optional warnings, including those which are not activated by -gnatwa. The use of this switch is not
recommended for normal use. If you turn this switch on, it is almost
certain that you will get large numbers of useless warnings. The
warnings that are excluded from -gnatwa are typically highly
specialized warnings that are suitable for use only in code that has
been specifically designed according to specialized coding rules.
And if you don't want to remove that switch, at least you can disable this specific info message:
-gnatw.Y
`Disable information messages for why package spec needs body.'
This switch suppresses the output of information messages showing why a package specification needs a body.

Getting errors while executing TDL code

[Collection:ExcelLedgersCollection]
ODBC: "Driver={Microsoft Excel Driver (*.xls,*.xlsx,*.xlsm,*.xlsb)};DBQ=C:\Desktop\List.xls"
SQL: "Select * from [Items$]"
[Function: ImportFromExcel]
Variable :TotalEntries :Number
Variable :Count :Number
00: Set :TotalEntries :$$NumItems:ExcelLedgersCollection
10: Start Progress: ##TotalEntries :"Items Creation" : "Importing Items in" : ##SVCurrentCompany
20: Walk Collection: ExcelLedgersCollection
30: New Object :Ledger
40: Set Value :Barcode :$_1
50: Set Value :Name :$_2
60: Set Value :Quantity :$_3
70: Create Target
80: Show Progres : ##Count
90: Increment : Count
100: End Walk
110: End Progress
120: Msg Box : "Status" : "Ledgers from Excel Imported Successfully"
[#Menu: Gateway of Tally]
Add: Item: Before:##locQuit: "Import From Excel" :Call :ImportFromExcel
I ran the above code and I am getting the following two errors:
1 FUNCTION 'ImportFromExcel' LABEL:10 Invalid number of steps 2
FUNCTION 'ImportFromExcel' LABEL:10 Action execution failed!
The function basically tries to read the data from the excel file called List.xls. I have googled these two errors and I found some suggestions:
The OS + Tally + Microsoft Office should all be either 32 bit or 64 bit.
The excel file name extension should be xls instead of xlsx.
I have a 64 bit system and I have checked to make sure that both Office and Tally are 64 bit. Also, my file extension is .xls. Any other ideas as to why this might not be working?
After setting Totalentries on line 00 (it may be safer to modify the line number to 001), try printing Totalentries by giving the command 002: log: ##Totalentries. It seems to me there are no values in your ExcelLedgersCollection collection.
1st we tried with Ms Office 2007 it never worked.
But when we used Ms Office 2019 it worked properly.
Following code works fine under MS Office 2019
[#Menu:Gateway Of TAlly]
Add:Item:Ledgerimport:Call: Ledgerimport
[Collection : Ledgerimport]
ODBC : "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=D:\Baby\Tally\TDL\Source1.xlsx"
SQL : "Select * From [Sheet1$]"
[Collection: ledsum]
Source Collection:Ledgerimport
Compute: lednm : $_1
;Compute: op:$$Number:$_3
Compute: pr:$_2
[Function:Ledgerimport]
Variable:var1:String
Variable:var2:String
;Variable:var3:String
00: Walk Collection: ledsum
01: Set: var1:$lednm
02: log:##var1
03: Set: var2:$op
04: log:##var2
07: New Object:Ledger
08: Set Value:Name:$$String:##var1
09: Set Value:Parent:"Sundry Debtors"
10: Set Value:Mailing name:"tst"
;11: Set Value: openingbalance:##var2
;
;12: Insert Collection Object:Address
;13: set Target:Address
;14: Set Value:Address:$$String:##var3;"Street1"
15: set Target:..
16: Create Target
17: End Walk
18: Msg Box: "warning" : "Ledger master created"
S.N.Ramkumar.
94444 52115

autohotkey soundset doesn't change mic

I'm trying to set my microphone to 50% with autohotkey but it only sets my master volume. I've tried
SoundSet 1, Microphone, 50
but it doesn't work. I also tried all the numbers up to 6.
I actually wrote something for this a while ago on the AHK subreddit. You can use this to toggle your mic volume to 50%. Pressing it again will set the volume back to whatever the original value was.
Give it a shot. If it doesn't work, let me know.
If it does, then you can mark your question answered.
Set your mic volume to something easy to remember but not common like 77. This is a temporary step to get the right audio device. You can change this later.
Run this script. PProvost wrote this and it can be found in the AHK Docs, too.
Look for the volume level that's set to 77. Note the component type (should look like Master:1), control type (most likely Volume or Microphone), and the mixer (which varies on each system. Mine was 10.)
;=============== Set This Stuff ===============
; Get this info from PProvost's script. If you lose the URL later, it's:
; https://github.com/PProvost/AutoHotKey/blob/master/SoundCardAnalysis.ahk
; Component Type
compType := "Master:1"
; Control Type
conType := "Volume"
; Mixer Number
mixer := 10
;Toggle tracker
toggle := 0
;=============== End "Set This Stuff" Section ===============
; Hotkey to set/toggle volume
F1::
; Tracks sound status
toggle = !toggle
; If toggle is turned on
if (toggle = 1){
; Save old setting
SoundGet, oldSound, % compType, % conType, % mixer
; Set new setting
SoundSet, 50, % compType, % conType, % mixer
; If toggle is off
}Else
; Revert to the old setting
SoundSet, % oldSound, % compType, % conType, % mixer
return
; Shift+Escape kills the app.
+Escape::ExitApp
I made my owm AHK with the response's help. I set it in my startup file and it sets my microphone volume to 30% every time I start up my computer (since my microphone is standard pretty loud)
Here is the code:
;=============== sauce ===============
; https://stackoverflow.com/questions/44330795/autohotkey-soundset-doesnt-change-mic
; https://github.com/PProvost/AutoHotKey/blob/master/SoundCardAnalysis.ahk
; Component Type
compType := "MASTER:1"
; Control Type
conType := "VOLUME"
; Mixer Number
mixer := 7
SoundSet, 31, % compType, % conType, % mixer

awk-insert row with specific text within specific position

I have a file where the first couple of rows start with # mark, then follow the classical netlist, where also can be there rows begin with # mark. I need to insert one row with text protect between block of first rows begining on # and first row of classical netlist. In the end of file i need insert row with word unprotect. It will be good to save this modified text to new file with specific name because of the original file protected.
Sample file:
// Generated for: spectre
// Design library name: Kovi
// Design cell name: T_Line
// Design view name: schematic
simulator lang=spectre
global 0
parameters frequency=3.8G Zo=250
// Library name: Kovi
// Cell name: T_Line
// View name: schematic
T8 (7 0 6 0) tline z0=Zo f=3.8G nl=0.5 vel=1
T7 (net034 0 net062 0) tline z0=Zo f=3.8G nl=0.5 vel=1
T5 (net021 0 4 0) tline z0=Zo f=3.8G nl=0.5 vel=1
T4 (net019 0 2 0) tline z0=Zo f=3.8G nl=0.5 vel=1
How about sed
sed -e '/^#/,/^#/!iprotect'$'\n''$aunprotect'$'\n' input_file > new_file
Inserts 'protect' on a line by itself after the first block of commented lines, then adds 'unprotect' at the end.
Note: Because I use $'\n' in place of literal newline bash is assumed as the shell.
Since you awk'd the post
awk 'BEGIN{ protected=""} { if($0 !~ /#/ && !protected){ protected="1"; print "protect";} print $0}END{print "unprotect";}' input_file > output_file
As soon a row is detected without # as the first non-whitespace character, it will output a line with protect. At the end it will output a line for unprotect.
Test file
#
#
#
#Preceded by a tab
begin protect
#
before unprotect
Result
#
#
#
#Preceded by tab
protect
begin protect
#
before unprotect
unprotect
Edit:
Removed the [:space:]* as it seems that is already handled by default.
Support //
If you wanted to support both # and // in the same script, the regex portion would change to /#|\//. The special character / has to be escaped by using \.
This would check for at least one /.
Adding a quantifier {2} will match // exactly: /#|\/{2}/

Check if file is a symlink in Freepascal

I'm reading various files and directories with the FindFirst / FindNext functions as described here.
The only problem I have, is that I can't figure out if the file is a symlink. In the file attributes there is no constant or flag and I can't find a function for testing for symlinks.
Your original idea of using findfirst is best, since it is a portable solution (windows has symlinks too nowadays). The only thing to adapt is to request symlink checking in the attributes you pass to findfirst:
uses sysutils;
var info : TSearchrec;
begin
// the or fasymlink in the next file is necessary so that findfirst
// uses (fp)lstat instead of (fp)stat
If FindFirst ('../*',faAnyFile or fasymlink ,Info)=0 then
begin
Repeat
With Info do
begin
If (Attr and fasymlink) = fasymlink then
Writeln('found symlink: ', info.name)
else
writeln('not a symlink: ', info.name,' ',attr);
end;
Until FindNext(info)<>0;
end;
FindClose(Info);
end.
You could use fpstat from BaseUnix:
Something like this
uses baseUnix;
var s: stat;
fpstat(filname, s);
if s.st_mode = S_IFLNK then
writeln('is link');
that also gives you a lot of other information about the file (times, size...)
The function fpLStat is the answer:
var
fileStat: stat;
begin
if fpLStat('path/to/file', fileStat) = 0 then
begin
if fpS_ISLNK(fileStat.st_mode) then
Writeln ('File is a link');
if fpS_ISREG(fileStat.st_mode) then
Writeln ('File is a regular file');
if fpS_ISDIR(fileStat.st_mode) then
Writeln ('File is a directory');
if fpS_ISCHR(fileStat.st_mode) then
Writeln ('File is a character device file');
if fpS_ISBLK(fileStat.st_mode) then
Writeln ('File is a block device file');
if fpS_ISFIFO(fileStat.st_mode) then
Writeln ('File is a named pipe (FIFO)');
if fpS_ISSOCK(fileStat.st_mode) then
Writeln ('File is a socket');
end;
end.
Prints out:
test_symlink
File is a link
test
File is a directory
Thanks for the hint using fpstat. But it does not seem to work.
I have two files, a directory and a symlink to a directory:
drwxrwxr-x 2 marc marc 4096 Okt 1 09:40 test
lrwxrwxrwx 1 marc marc 11 Dez 5 13:49 test_symlink -> /home/marc/
If I use fpstat on these to files I get:
Result of fstat on file test
Inode : 23855105
Mode : 16877
nlink : 92
uid : 1000
gid : 1000
rdev : 0
Size : 12288
Blksize : 4096
Blocks : 24
atime : 1354711751
mtime : 1354711747
ctime : 1354711747
Result of fstat on file test_symlink
Inode : 23855105
Mode : 16877
nlink : 92
uid : 1000
gid : 1000
rdev : 0
Size : 12288
Blksize : 4096
Blocks : 24
atime : 1354711751
mtime : 1354711747
ctime : 1354711747
No difference in Attribute st_mode. I think that fpstat gets the stats of the link destination, which indeed is a directory...

Resources