Page 1 of 3
Logic(_cast... crashes VO & DBCreate question
Posted: Tue Mar 09, 2021 2:00 pm
by ic2
Basically my problem is that every time I resume working on an older X# project with a newer X# version installed I am getting al kind of new problems which are difficult to detect and solve.
1 This used to work:
RDDSetDefault("DBFCDX")
oExcel:=ApplicationClass{}
oExcel:Visible:=False // Don't show the EXCEL execute
oExcel:DisplayAlerts:=False // Don't show messages
oWorkBooks:=oExcel:Workbooks
ofd:=Microsoft.Win32.OpenFileDialog{}
ofd:Filter:="Excel Files|*.xlsx;*.xls"
lResult:=ofd:ShowDialog()
I had to change the last line as follows because of error XS0266 Cannot implicitely convert type logic? to logic
lResult:=Logic(_cast,ofd:ShowDialog())
Now, the first time I actually created the X# DLL to be used in VO, with some changes (see below) VO crashed with a 5333 (also when there's an error handler Try/Catch; it doesn't show a run time error). It took me nearly an hour, by gradually adding code, to find out where it went wrong:
lResult:=Logic(_cast,ofd:ShowDialog())
causes the 5333. If I just make it ofd:ShowDialog() it works, but I can not read the result of opening the file!
How can I get this working without crashing VO? I tried to disable this error with the #pragma statement but that does only seem to work with warnings.
Edit: Also I am not seeing how you have declared the "ofd" variable. That should be
LOCAL ofd AS Microsoft.Win32.OpenFileDialog
2 The reason why I had to change the program is that when I create the DBF (from an Excel file) I get this error:
Vulcan.NET Runtime Error
Error Code: 1 [Argument error]
Error Subcode: 1015 [RDD not found]
which seems to indicate that
If DBCreate("ExcelImport.dbf", aDBF) does no longer work (it used to!) and requires at least DBFCDX to be supplied, I thought:
If DBCreate("ExcelImport.dbf", aDBF,"DBFCDX")
But it doesn't work with DBFCDX filled in either. Also this used to work fine. Note that I use the Vulcan DLL's because of multiple problems with the X# DBF DLL's.
So why do I get this error? I have copied all the DLL's and there are no X# specific RDD's as far as I can see?
3 And another thing which intrigued me is why the last parameters of the DBCreate method differ from those in VO?
Dick
Logic(_cast... crashes VO & DBCreate question
Posted: Tue Mar 09, 2021 2:27 pm
by FFF
Dick,
you don't say, which version you use, that doesn't help...
In the What's new for 2.7 there is "Fixed a problem with Nullable types that were missing an explicit cast for an assignment" - if you look into MS doc you see ShowDialog() returns a "bool?" - not a "bool". Hence the error. If you are on 2.6 it might be related to this fix.
I have no clue of these new things, but couldn't you type your "lResult as logic?" (insteat of "logic")?
(I hate all these question marks...)
Re 2 i have no clue, but from the help this should be the same as in VO.
Re 3 i see no difference
And finally: If you have "multiple problems with X# Dlls", it would be nice, if you post them - hence others won't get trapped - and dev has a chance to fix them.
EDIT: Re1: i added this to a X# Standard MDI sample (after adding reference to "Presentation")
VAR ofd:=Microsoft.Win32.OpenFileDialog{}
ofd:Filter:="Excel Files|*.xlsx;*.xls"
VAR lResult:=ofd:ShowDialog()
No warning, dialog shown, filter set.
Logic(_cast... crashes VO & DBCreate question
Posted: Tue Mar 09, 2021 3:53 pm
by Chris
Hi Dick,
1. What changed is a fix we made in the compiler (as Karl pointed out), because there was a problem previously in this area, with Nullable types and in this case ShowDialog() returns a Nullable LOGIC. It was working for you before in this case only by coincidence, because apparently this particular method only returns TRUE or FALSE and never NULL. Other similar code would had failed, and now we have fixed that, but the change means that now you need to use correct code when dealing with Nullables.
Nullable LOGICs have 3 states, TRUE, FALSE or NULL. The correct way to read the value is to query first if the return type has a value (TRUE or FALSE) and only then read it:
Code: Select all
lRetValue := ofd:ShowDialog()
IF lRetValue:HasValue
lResult := lRetValue:Value
ELSE
// what does NULL return value mean? Maybe handle it as FALSE, too?
lResult := FALSE
END IF
if you are absolutely sure that the method never returns NULL (which according to the docs appears to be the case with ShowDialog() here), then you could have also read the logic value directly, but this is really sloppy coding when dealing with nullables:
2. This does work fine still. Could it be the error is reported in some other part of your code?
3. Which ones are different? They look to be exactly the same here.
Logic(_cast... crashes VO & DBCreate question
Posted: Tue Mar 09, 2021 6:03 pm
by ic2
Hello Chris, Karl,I tried this code (combining both your replies):
LOCAL lResult as USUAL
Var lRetValue:=ofd:ShowDialog()
If lRetValue:HasValue
lResult:=lRetValue
Endif
If lResult == False
Return
Else
cExcelFile:=ofd:FileName
Endif
That works indeed, thanks, but I am not comfortable with the USUAL. Can I change that and how?
2 See attached the full error message. This seems to fail at DBCreate. I just can't figure out what is supposed to be missing (or wrong)?
It is not possible to debug this as it's a DLL called from VO but I have added a Messagebox just before and just after the DBCreate and the first shows and before the 2nd can be reached I have the error message.
Note that this works, at the start of the program:
RDDSetDefault("DBFCDX")
and this fails:
If DBCreate("ExcelImport.dbf", aDBF,"DBFCDX",True,"","",False) // Create the DBF
and omitting DBFCDX gives an exception String can not have zero length.
According to the help:
If not specified, the default RDD as determined by RDDSetDefault() is used.
so that doesn't seem to work as specified either:
If DBCreate("ExcelImport.dbf", aDBF,"",True,"","",False) // Create the DBF
3 I think you are right. VO calls it:
DBCreate(<cTargetFile>, <aStruct>, [<cDriver>], [<lNew>], [<cAlias>], [<cDelim>], [<lOpen>],, [<acRDDs>]) ---> lSuccess
and the tooltip in X# calls the last 2 parameters lJustOpen and aHidden. No idea why the latter is called aHidden but I assume it is the same array as VO's acRDDs.
Dick
Logic(_cast... crashes VO & DBCreate question
Posted: Tue Mar 09, 2021 6:35 pm
by Chris
Hi Dick,
1. No need to use a USUAL, just type it AS LOGIC
2. Oh, I forgot that this is called from VO. Did you include the code to initialize the vulcan rdd? You must have needed this also before.
About the driver name, the help file says you can omit this parameter, but in this case you are not omitting it, you are passing an empty string instead. Omitting it would look like:
DBCreate("ExcelImport.dbf", aDBF, ,True)
3. If you see the tooltip in VO, it has the exact same parameter names as in X#/Vulcan
Logic(_cast... crashes VO & DBCreate question
Posted: Tue Mar 09, 2021 6:55 pm
by FFF
Chris,
typing as logic won't work, compiler won't accept it.
But LOCAL lResult AS LOGIC?
works.
Dick,
either the above, or my
VAR lResult := ofd:ShowDialog()
should work.
Logic(_cast... crashes VO & DBCreate question
Posted: Tue Mar 09, 2021 7:04 pm
by Chris
Hi Karl,
It doesn't work, because Dick changed the code from "lResult := lRetValue:Value" to "lResult := lRetValue". The correct first version of the code works. But anyway since the return value is not being used anywhere later as far as I can see, then the code can be simply written as
Code: Select all
LOCAL lResult AS Nullable<LOGIC>
lResult := ofd:ShowDialog()
IF lResult:HasValue .and. lResult:Value == TRUE
cExcelFile := ofd:FileName
ELSE
RETURN
ENDIF
Logic(_cast... crashes VO & DBCreate question
Posted: Tue Mar 09, 2021 7:35 pm
by FFF
Ah, i see.
FTR: it seems,
LOCAL lResult AS Nullable<LOGIC>
is equal to
LOCAL lResult AS LOGIC?
Logic(_cast... crashes VO & DBCreate question
Posted: Tue Mar 09, 2021 7:53 pm
by Chris
Yes, it's exactly the same thing, I just prefer the Nullable<> version because for me it's more readable.
Logic(_cast... crashes VO & DBCreate question
Posted: Tue Mar 09, 2021 8:10 pm
by ic2
1. No need to use a USUAL, just type it AS LOGIC
LOCAL lResult AS Nullable<LOGIC>
That works indeed, thanks.
2. Oh, I forgot that this is called from VO. Did you include the code to initialize the vulcan rdd? You must have needed this also before.
It worked before as it is now, but what should I do to initialize?
About the driver name, the help file says you can omit this parameter, but in this case you are not omitting it, you are passing an empty string instead. Omitting it would look like:
Ah, of course. But then it still doesn't work.
Maybe the initialize helps....
Dick