Need input on Intel Fortran to MS Excel Interfaces

Need input on Intel Fortran to MS Excel Interfaces

I recently moved over to Intel Fortran Development environment. I would like to add the capability in my FORTRAN program to write the results to MS Excel files and draw some charts. Right now I print the results to text files and use VBA macro to read data from text files, and plot excel charts. The VBA debugging is painful (maybe because I am not good in VBA) and I feel home in FORTRAN environment.

So the objective is to make FORTRAN to write to Excel files. I can not decide on what is the best way to do this. I would like to stay with native FORTRAN environment, because I don't know much in VB.NET.

I came across f90VB, which is mean entirely for this purpose. But it is not being sold anymore (and I don't think it works with Visual Studio 2005).

Are there any other standard libraries or codes that will support creating Excel files from FORTRAN?

The examples in ifort ver 9 or 10, have mixed language programming calls from VB to FORTRAN (meaning the main function is in VB, and FORTRAN calls are through DLLs). I would prefer something from FORTRAN to VB (where FORTRAN remains in control). Because right now my program is tuned for that, otherwise I will have to redesign the code. In future, I am also thinking about generating a GUI environment for the FORTRAN program.

Considering the things said above, and based on your experience, could somebody suggest me what the best way to approach this problem is? I don't mind spending time to learn VB.NET or some other technique or library or language, but it should be worthwhile.

Your input is much appreciated and will save me time in doing things the right way.

Thanks in advance.

12 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

After a prolonged search for a solution for this topic, I came across one of the posts in Google Groups in comp.lang.fortran that said intel fortran has the following:

there's a tool for creating interface specifications for
calling COM code, and I think you can use that for Excel automation.

Could someone please give me some indeas on where to look for a sample example. Is it possible to proceed along the above lines to get a fortran-excel-fortran interface working?

Thanks.

I would suggest you first look at the free f90SQL library. I don't know if it can create Excel files, but it can certaiinly talk to Excel. This would be the preferable approach if it works for you.

You can use the Fortran Module Wizard tool to generate COM interfaces to Excel, and many people have done this. You can read about the Module Wizard in the compiler documentation.

CVF had a sample application which I have not tried with Intel Fortran yet - when I'm back in the office next week I'll try it and see how it works.

Steve - Intel Developer Support

Steve,

Thanks for your kind words about trying to port the sample application from CVF to ifort. I just looked up the CVF examples and there is an AUTODICE example that looks similar to what you just said. It sure looks intimidating for me to attempt a port to ifort.

If you could work on an example and show us how to achieve it in a pure fortran way, that would be a great. This would permanently prevent any future discussions on "ifort to excel" topic and whether ifort can do it.

Meanwhile, I will download the f90SQL library and give it a shot.

Thanks.

Actually, the CVF sample ports without much problem at all. I've done so, with some minor updating, and attached it here. The tricky thing is to understand the Excel COM interface, which I assume MS has documented somewhere. That is not something I'm an expert on.

Attachments: 

AttachmentSize
Downloadapplication/zip AutoDice.zip78.5 KB
Steve - Intel Developer Support

Need some help with linker errors. I am using IVF 9 (Although I download IVF 10,could not gather enough courage to actually install it) and excel 11. Are the link errors due to ver 9 of the compiler or due to something else?

Error1 error LNK2019: unresolved external symbol __imp__VariantInit@4 referenced in function _NewInvokeArgC:Documents and Settings
sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error2 error LNK2019: unresolved external symbol __imp__SysAllocString@4 referenced in function _OLECFSTRINGTOBSTR.C:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error3 error LNK2019: unresolved external symbol __imp__SysFreeString@4 referenced in function _AUTODEALLOCATEINVOKEARGSC:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error4 error LNK2019: unresolved external symbol __imp__SafeArrayDestroy@4 referenced in function _CleanUpVariantC:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error5 error LNK2019: unresolved external symbol __imp__VariantChangeType@16 referenced in function _SetResultC:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error6 error LNK2019: unresolved external symbol __imp__SysStringLen@4 referenced in function _SetResultC:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error7 error LNK2019: unresolved external symbol __imp__SafeArrayGetDim@4 referenced in function _SetResultC:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error8 error LNK2019: unresolved external symbol __imp__SafeArrayGetLBound@12 referenced in function _SetResultC:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error9 error LNK2019: unresolved external symbol __imp__SafeArrayGetUBound@12 referenced in function _SetResultC:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error10 error LNK2019: unresolved external symbol __imp__SafeArrayGetElement@12 referenced in function _SetResultC:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error11 error LNK2019: unresolved external symbol _SafeArrayCreate@12 referenced in function _AUTOADDARG2INTEGER2ARRAYC:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error12 error LNK2019: unresolved external symbol _SafeArrayPutElement@12 referenced in function _AUTOADDARG2INTEGER2ARRAYC:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error13 error LNK2019: unresolved e xternal symbol _SysFreeString@4 referenced in function _AUTOADDARG2CHARACTERARRAYC:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error14 error LNK2019: unresolved external symbol _MAIN__ referenced in function _mainC:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901
Error15 fatal error LNK1120: 14 unresolved externalsC:Documents and Settings sankaraMy DocumentsFortranAutoDiceEXCEL.f901

Update: I was able to successfully compile the code. I use IVF9 with VS2005 (standard). So I created a new project (console application) and inserted the three fortran files from autodice. Eveything runs fine.

Thanks steve. If you could include this project in the list of sample in future versions of IVF that would be useful to a majority of IVF users.

I'm in the process of adding this to the samples for a future version. I'm glad to hear that it helps you. For more reading on Office automation, see http://support.microsoft.com/ofd

Steve - Intel Developer Support

The att. code contains sample routines for creating and then populating an Excel spreadsheet, all from IVF.


!==== Module initialiations & variables
USE IFWINTY
USE IFAUTO
USE IFCOM

! Variables
INTEGER*4 status

! Object Pointers
INTEGER*4 excelapp
INTEGER*4 workbooks
INTEGER*4 workbook
INTEGER*4 worksheet


!==== Sample Excel initialization code ========
! res is an error return (set to 0 on success)

CALL COMINITIALIZE (status)

! Initialize object pointers
excelapp = 0
workbooks = 0
workbook = 0
worksheet = 0

! Create an Excel object
res = 1
CALL COMCREATEOBJECT ("Excel.Application", excelapp, status)
IF (excelapp == 0) RETURN
CALL $Application_SetVisible (excelapp, .TRUE.)
CALL $Application_SetScreenUpdating (excelapp, .FALSE.)

! get its window handle
hwnd_ChildProcess = GetForegroundWindow ()

! Get the WORKBOOKS object
res = 2
workbooks = $Application_GetWorkbooks (excelapp, $STATUS = status)
IF (status /= 0) RETURN

! Open a new spreadsheet from the template file
res = 3
workbook = Workbooks_Open (workbooks, tbuf, $STATUS = status)
IF (status /= 0) RETURN

! Get the worksheet
res = 4
worksheet = $Workbook_GetActiveSheet (workbook, status)
IF (status /= 0) RETURN

! code goes here to populate cells, prepare the worksheet;
! see utility routines below

CALL $Application_SetScreenUpdating (excelapp, .TRUE.)

!======= When we are done...

! release all objects which may have been created
IF (worksheet /= 0) status = COMRELEASEOBJECT (worksheet)
IF (workbook /= 0) status = COMRELEASEOBJECT (workbook )
IF (workbooks /= 0) status = COMRELEASEOBJECT (workbooks)
IF (excelapp /= 0) status = COMRELEASEOBJECT (excelapp )

CALL COMUNINITIALIZE()



!================






SUBROUTINE PutRealInCell (column, row, argval)
IMPLICIT NONE
CHARACTER(LEN=*), INTENT(IN) :: column
INTEGER, INTENT(IN) :: row
REAL, INTENT(IN) :: argval
INTEGER :: range

range = column_range (column, row)

status = AUTOSETPROPERTYREAL4 (range, "VALUE", argval)

END SUBROUTINE PutRealInCell


SUBROUTINE PutTextInCell (column, row, string, width)
IMPLICIT NONE
CHARACTER(LEN=*), INTENT(IN) :: column
INTEGER, INTENT(IN) :: row
CHARACTER(LEN=*), INTENT(INOUT) :: string
INTEGER, INTENT(IN), OPTIONAL :: width
INTEGER :: range

range = column_range (column, row)

IF (PRESENT(width)) &
status = AUTOSETPROPERTYINTEGER2 (range, "ColumnWidth", width)

CALL NullTerminateString (string)
status = AUTOSETPROPERTYCHARACTER (range, "VALUE", string)

END SUBROUTINE PutTextInCell


INTEGER FUNCTION column_range (column, row1, row2) RESULT (range)
IMPLICIT NONE
CHARACTER(LEN=*), INTENT(IN) :: column
INTEGER, INTENT(IN) :: row1
INTEGER, INTENT(IN), OPTIONAL :: row2
CHARACTER(LEN=12) :: cell_id
TYPE(VARIANT) :: vBSTR1, vBSTR2
INTEGER*4 :: pBSTR1, pBSTR2

WRITE (cell_id, '(A,I6,A)') column, row1, CHAR(0)
pBSTR1 = leftpack (cell_id)

CALL VariantInit (vBSTR1)
vBSTR1%VT = VT_BSTR
pBSTR1 = StringToBSTR (cell_id)
vBSTR1%V U%PTR_VAL = pBSTR1

IF (PRESENT(row2)) THEN
WRITE (cell_id, '(A,I6,A)') column, row1, CHAR(0)
pBSTR2 = leftpack (cell_id)
CALL VariantInit (vBSTR2)
vBSTR2%VT = VT_BSTR
pBSTR2 = StringToBSTR (cell_id)
vBSTR2%VU%PTR_VAL = pBSTR2
range = $Worksheet_GetRange (worksheet, vBSTR1, vBSTR2, $STATUS=status)
status = VariantClear(vBSTR2)
IF (pBSTR2 /= 0) CALL SysFreeString (pBSTR2)

ELSE
range = $Worksheet_GetRange (worksheet, vBSTR1, $STATUS=status)

END IF
status = VariantClear(vBSTR1)
IF (pBSTR1 /= 0) CALL SysFreeString (pBSTR1)
END FUNCTION column_range


SUBROUTINE worksheet_setup
IMPLICIT NONE
INTEGER :: range
TYPE(VARIANT) :: vBSTR1, vBSTR2
INTEGER*4 :: pBSTR1, pBSTR2
INTEGER, PARAMETER :: xlRight = -4152 ! #HFFFFEFC8

CALL VariantInit (vBSTR1)
vBSTR1%VT = VT_BSTR
pBSTR1 = StringToBSTR ('A1'//CHAR(0))
vBSTR1%VU%PTR_VAL = pBSTR1

CALL VariantInit (vBSTR2)
vBSTR2%VT = VT_BSTR
pBSTR2 = StringToBSTR ('J5002'//CHAR(0))
vBSTR2%VU%PTR_VAL = pBSTR2

range = $Worksheet_GetRange (worksheet, vBSTR1, vBSTR2, $STATUS=status)

!status = AUTOSETPROPERTYINTEGER2 (range, "ClearContents", 1)
status = AUTOSETPROPERTYINTEGER2 (range, "FontSize", INT2(8))
status = AUTOSETPROPERTYINTEGER2 (range, "HorizontalAlignment", INT2(xlRight))
status = AUTOSETPROPERTYINTEGER2 (range, "RowHeight", INT2(10))

status = VariantClear(vBSTR1)
IF (pBSTR1 /= 0) CALL SysFreeString (pBSTR1)
status = VariantClear(vBSTR2)
IF (pBSTR2 /= 0) CALL SysFreeString (pBSTR2)
END SUBROUTINE worksheet_setup


SUBROUTINE NullTerminateString (string)
IMPLICIT NONE
CHARACTER(LEN=*), INTENT(INOUT) :: string
INTEGER :: nc, ncmax
ncmax = LEN(string)
nc = chcnt(string, ncmax)
IF (nc == 0) THEN
string(1:1) = CHAR(0)
ELSE
nc = MIN0(nc+1, ncmax)
string(nc:nc) = CHAR(0)
END IF
END SUBROUTINE NullTerminateString


RECURSIVE FUNCTION chcnt (text, ncmax) RESULT (nc)
IMPLICIT NONE
CHARACTER(LEN=*),INTENT(IN) :: text
INTEGER,INTENT(IN) :: ncmax
INTEGER :: nc
DO nc = MIN0(LEN(text),ncmax),1,-1
IF (ICHAR(text(nc:nc)) > 32) RETURN
END DO
nc = 0
END FUNCTION chcnt




! Routines copied from Excel97a.f90, so we don't need to include
! that entire module (very slow compilation under IVF); omitting
! the balance of unused routines also trims about 200Kb from the
! size of the executable file

! renamed from ConvertStringToBstr(), which has a linker conflict
INTEGER(INT_PTR_KIND()) FUNCTION StringToBSTR(string)
USE OLEAUT32
USE IFNLS
CHARACTER*(*), INTENT(IN) :: string
INTEGER(INT_PTR_KIND()) bstr
INTEGER*4 length
INTEGER*2, ALLOCATABLE :: unistr(:)
! First call to MBConvertMBToUnicode determines the length to allocate
ALLOCATE (unistr(0))
length = MBConvertMBToUnicode(string, unistr)
DEALLOCATE (unistr)
! Special case for all spaces
IF (length < 0) THEN
ALLOCATE (unistr(2))
unistr(1) = #20 ! Single space
unistr(2) = 0 ! Null terminate
ELSE
! Second call to MBConvertMBToUnicode does the conversion
ALLOCATE (unistr(length+1))
length = MBConvertMBToUnicode(string, unistr)
unistr(length +1) = 0 ! Null terminate
END IF
bstr = SysAllocString(unistr)
DEALLOCATE (unistr)
StringToBSTR = bstr
END FUNCTION StringToBSTR


SUBROUTINE $Application_SetVisible($OBJECT, $ARG1, $STATUS)
!! !DEC$ ATTRIBUTES DLLEXPORT :: $Application_SetVisible
IMPLICIT NONE

INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer
!DEC$ ATTRIBUTES VALUE :: $OBJECT
LOGICAL*2, INTENT(IN) :: $ARG1
!DEC$ ATTRIBUTES REFERENCE :: $ARG1
INTEGER*4, INTENT(OUT), OPTIONAL :: $STATUS ! Method status
!DEC$ ATTRIBUTES REFERENCE :: $STATUS
INTEGER*4 $$STATUS
INTEGER(INT_PTR_KIND()) invokeargs
invokeargs = AUTOALLOCATEINVOKEARGS()
CALL AUTOADDARG(invokeargs, 'Visible', $ARG1)
$$STATUS = AUTOSETPROPERTYBYID($OBJECT, 558, invokeargs)
IF (PRESENT($STATUS)) $STATUS = $$STATUS
CALL AUTODEALLOCATEINVOKEARGS (invokeargs)
END SUBROUTINE $Application_SetVisible

SUBROUTINE $Application_SetScreenUpdating($OBJECT, $ARG1, $STATUS)
!! !DEC$ ATTRIBUTES DLLEXPORT :: $Application_SetScreenUpdating
IMPLICIT NONE

INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer
!DEC$ ATTRIBUTES VALUE :: $OBJECT
LOGICAL*2, INTENT(IN) :: $ARG1
!DEC$ ATTRIBUTES REFERENCE :: $ARG1
INTEGER*4, INTENT(OUT), OPTIONAL :: $STATUS ! Method status
!DEC$ ATTRIBUTES REFERENCE :: $STATUS
INTEGER*4 $$STATUS
INTEGER(INT_PTR_KIND()) invokeargs
invokeargs = AUTOALLOCATEINVOKEARGS()
CALL AUTOADDARG(invokeargs, 'ScreenUpdating', $ARG1)
$$STATUS = AUTOSETPROPERTYBYID($OBJECT, 382, invokeargs)
IF (PRESENT($STATUS)) $STATUS = $$STATUS
CALL AUTODEALLOCATEINVOKEARGS (invokeargs)
END SUBROUTINE $Application_SetScreenUpdating

INTEGER(INT_PTR_KIND()) FUNCTION $Application_GetWorkbooks($OBJECT, $STATUS)
!! !DEC$ ATTRIBUTES DLLEXPORT :: $Application_GetWorkbooks
IMPLICIT NONE

INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer
!DEC$ ATTRIBUTES VALUE :: $OBJECT
INTEGER*4, INTENT(OUT), OPTIONAL :: $STATUS ! Method status
!DEC$ ATTRIBUTES REFERENCE :: $STATUS
INTEGER*4 $$STATUS
INTEGER(INT_PTR_KIND()) invokeargs
INTEGER(INT_PTR_KIND()), VOLATILE :: $RETURN
invokeargs = AUTOALLOCATEINVOKEARGS()
CALL AUTOADDARG(invokeargs, 'Workbooks', $RETURN, AUTO_ARG_OUT, VT_DISPATCH)
$$STATUS = AUTOGETPROPERTYBYID($OBJECT, 572, invokeargs)
IF (PRESENT($STATUS)) $STATUS = $$STATUS
$Application_GetWorkbooks = $RETURN
CALL AUTODEALLOCATEINVOKEARGS (invokeargs)
END FUNCTION $Application_GetWorkbooks

INTEGER(INT_PTR_KIND()) FUNCTION Workbooks_Open($OBJECT, Filename, UpdateLinks, ReadOnly, Fformat, Password, WriteResPassword, IgnoreReadOnlyRecommended, Origin, Delimiter, Editable, Notify, Converter, AddToMru, $STATUS)
!! !DEC$ ATTRIBUTES DLLEXPORT :: Workbooks_Open
IMPLICIT NONE

INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer
!DEC$ ATTRIBUTES VALUE :: $OBJECT
CHARACTER*(*), INTENT(IN) :: Filename ! BSTR
!DEC$ ATTRIBUTES REFERENCE :: Filename
TYPE (VARIANT), INTENT(IN), OPTIONAL :: UpdateLinks
!DEC$ ATTRIBUTES REFERENCE :: UpdateLinks
TYPE (VARIANT), INTENT(IN), OPTIONAL :: ReadOnly
!DEC$ ATTRIBUTES REFERENCE :: ReadOnly
TYPE (VARIANT), INTENT(IN), OPTIONAL :: Fformat
!DEC$ ATTRIBUTES REFERENCE :: Fformat
TYPE (VARIANT), INTENT(IN), OPTIONAL :: Password
!DEC$ ATTRIBUTES REFERENCE :: P assword
TYPE (VARIANT), INTENT(IN), OPTIONAL :: WriteResPassword
!DEC$ ATTRIBUTES REFERENCE :: WriteResPassword
TYPE (VARIANT), INTENT(IN), OPTIONAL :: IgnoreReadOnlyRecommended
!DEC$ ATTRIBUTES REFERENCE :: IgnoreReadOnlyRecommended
TYPE (VARIANT), INTENT(IN), OPTIONAL :: Origin
!DEC$ ATTRIBUTES REFERENCE :: Origin
TYPE (VARIANT), INTENT(IN), OPTIONAL :: Delimiter
!DEC$ ATTRIBUTES REFERENCE :: Delimiter
TYPE (VARIANT), INTENT(IN), OPTIONAL :: Editable
!DEC$ ATTRIBUTES REFERENCE :: Editable
TYPE (VARIANT), INTENT(IN), OPTIONAL :: Notify
!DEC$ ATTRIBUTES REFERENCE :: Notify
TYPE (VARIANT), INTENT(IN), OPTIONAL :: Converter
!DEC$ ATTRIBUTES REFERENCE :: Converter
TYPE (VARIANT), INTENT(IN), OPTIONAL :: AddToMru
!DEC$ ATTRIBUTES REFERENCE :: AddToMru
INTEGER*4, INTENT(OUT), OPTIONAL :: $STATUS ! Method status
!DEC$ ATTRIBUTES REFERENCE :: $STATUS
INTEGER*4 $$STATUS
INTEGER(INT_PTR_KIND()) invokeargs
INTEGER(INT_PTR_KIND()), VOLATILE :: $RETURN

invokeargs = AUTOALLOCATEINVOKEARGS()
CALL AUTOADDARG (invokeargs, '$RETURN', $RETURN, AUTO_ARG_OUT, VT_DISPATCH)
CALL AUTOADDARG (invokeargs, '$ARG1', Filename, AUTO_ARG_IN, VT_BSTR)

IF (PRESENT(UpdateLinks)) CALL AUTOADDARG (invokeargs, '$ARG2', UpdateLinks, AUTO_ARG_IN)
IF (PRESENT(ReadOnly)) CALL AUTOADDARG (invokeargs, '$ARG3', ReadOnly, AUTO_ARG_IN)
IF (PRESENT(Fformat)) CALL AUTOADDARG (invokeargs, '$ARG4', Fformat, AUTO_ARG_IN)
IF (PRESENT(Password)) CALL AUTOADDARG (invokeargs, '$ARG5', Password, AUTO_ARG_IN)
IF (PRESENT(WriteResPassword)) &
CALL AUTOADDARG (invokeargs, '$ARG6', WriteResPassword, AUTO_ARG_IN)
IF (PRESENT(IgnoreReadOnlyRecommended)) &
CALL AUTOADDARG (invokeargs, '$ARG7', IgnoreReadOnlyRecommended, AUTO_ARG_IN)
IF (PRESENT(Origin)) CALL AUTOADDARG (invokeargs, '$ARG8', Origin, AUTO_ARG_IN)
IF (PRESENT(Delimiter)) CALL AUTOADDARG (invokeargs, '$ARG9', Delimiter, AUTO_ARG_IN)
IF (PRESENT(Editable)) CALL AUTOADDARG (invokeargs, '$ARG10', Editable, AUTO_ARG_IN)
IF (PRESENT(Notify)) CALL AUTOADDARG (invokeargs, '$ARG11', Notify, AUTO_ARG_IN)
IF (PRESENT(Converter)) CALL AUTOADDARG (invokeargs, '$ARG12', Converter, AUTO_ARG_IN)
IF (PRESENT(AddToMru)) CALL AUTOADDARG (invokeargs, '$ARG13', AddToMru, AUTO_ARG_IN)

$$STATUS = AUTOINVOKE($OBJECT, 682, invokeargs)
IF (PRESENT($STATUS)) $STATUS = $$STATUS
Workbooks_Open = $RETURN
CALL AUTODEALLOCATEINVOKEARGS (invokeargs)
END FUNCTION Workbooks_Open

INTEGER(INT_PTR_KIND()) FUNCTION $Workbook_GetActiveSheet($OBJECT, $STATUS)
!! !DEC$ ATTRIBUTES DLLEXPORT :: $Workbook_GetActiveSheet
IMPLICIT NONE

INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer
!DEC$ ATTRIBUTES VALUE :: $OBJECT
INTEGER*4, INTENT(OUT), OPTIONAL :: $STATUS ! Method status
!DEC$ ATTRIBUTES REFERENCE :: $STATUS
INTEGER*4 $$STATUS
INTEGER(INT_PTR_KIND()) invokeargs
INTEGER(INT_PTR_KIND()), VOLATILE :: $RETURN
invokeargs = AUTOALLOCATEINVOKEARGS()
CALL AUTOADDARG(invokeargs, 'ActiveSheet', $RETURN, AUTO_ARG_OUT, VT_DISPATCH)
$$STATUS = AUTOGETPROPERTYBYID($OBJECT, 307, invokeargs)
IF (PRESENT($STATUS)) $STATUS = $$STATUS
$Workbook_GetActiveSheet = $RETURN
CALL AUTODEALLOCATEINVOKEARGS (invokeargs)
END FUNCTION $Workbook_GetActiveSheet

INTEGER(INT_PTR_KIND()) FUNCTION $Worksheet_GetRange($OBJECT, Cell1, Cell2, $STATUS)
!! !DEC$ ATTRIBUTES DLLEXPORT :: $Worksheet_GetRange
IMPLICIT NONE

INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer
!DEC$ ATTRIBUTES VALUE :: $OBJECT
TYPE (VARIANT), INTENT(IN) :: Cell1
!DEC$ ATTRIBUTES REFERENCE :: Cell1
TYPE (VARIANT), INTENT(IN), OPTIONAL :: Cell2
!DEC$ ATTRIBUTES REFERENCE :: Cell2
INTEGER*4, INTENT(OUT), OPTIONAL :: $STATUS ! Method status
!DEC$ ATTRIBUTES REFERENCE :: $STATUS
INTEGER*4 $$STATUS
INTEGER(INT_PTR_KIND()) invokeargs
INTEGER(INT_PTR_KIND()), VOLATILE :: $RETURN
invokeargs = AUTOALLOCATEINVOKEARGS()
CALL AUTOADDARG(invokeargs, 'Range', $RETURN, AUTO_ARG_OUT, VT_DISPATCH)
CALL AUTOADDARG(invokeargs, '$ARG1', Cell1, AUTO_ARG_IN)
IF (PRESENT(Cell2)) CALL AUTOADDARG(invokeargs, '$ARG2', Cell2, AUTO_ARG_IN)
$$STATUS = AUTOGETPROPERTYBYID($OBJECT, 197, invokeargs)
IF (PRESENT($STATUS)) $STATUS = $$STATUS
$Worksheet_GetRange = $RETURN
CALL AUTODEALLOCATEINVOKEARGS (invokeargs)
END FUNCTION $Worksheet_GetRange


Thanks Paul-Curtis and Steve for new AUTODICE examples. You had provided good samples that people can use to get started on FORTRAN to EXCEL using COM.

I will compile Paul's code later and keep you updated.

qtXLS might also be a solution to you.

http://www.qtsoftware.de/vertrieb/db/qtxls_e.htm

This library allows to read/write EXCEL files.

...or F90VB from Canaimasoft.. see http://www.canaimasoft.com/f90VB/Index.htm(I have no connection with them)

Leave a Comment

Please sign in to add a comment. Not a member? Join today