0 penilaian0% menganggap dokumen ini bermanfaat (0 suara)
53 tayangan7 halaman
This document discusses how to call FORTRAN code from Excel and VBA by building a DLL file. It provides an example FORTRAN code that calculates a friction factor, compiles it into a DLL, and calls the FORTRAN function from VBA. It notes the necessary attributes for exporting FORTRAN subs/functions to the DLL and data type mappings between FORTRAN and VBA. The VBA code example also demonstrates passing arrays between FORTRAN and VBA by resizing and populating the arrays in VBA before calling the FORTRAN subroutine.
This document discusses how to call FORTRAN code from Excel and VBA by building a DLL file. It provides an example FORTRAN code that calculates a friction factor, compiles it into a DLL, and calls the FORTRAN function from VBA. It notes the necessary attributes for exporting FORTRAN subs/functions to the DLL and data type mappings between FORTRAN and VBA. The VBA code example also demonstrates passing arrays between FORTRAN and VBA by resizing and populating the arrays in VBA before calling the FORTRAN subroutine.
This document discusses how to call FORTRAN code from Excel and VBA by building a DLL file. It provides an example FORTRAN code that calculates a friction factor, compiles it into a DLL, and calls the FORTRAN function from VBA. It notes the necessary attributes for exporting FORTRAN subs/functions to the DLL and data type mappings between FORTRAN and VBA. The VBA code example also demonstrates passing arrays between FORTRAN and VBA by resizing and populating the arrays in VBA before calling the FORTRAN subroutine.
Written by Christos Samaras on Wednesday, 26 March 2014 at 02:31
Introduction
According to Wikipedia: FORTRAN (derived from FORmula TRANslating System) is a general-purpose, imperative programming language that is especially suited to numeric computation and scientific computing. Originally developed by IBM in New York City in the 1950s for scientific and engineering applications, FORTRAN came to dominate this area of programming early on and has been in continuous use for over half a century in computationally intensive areas such as numerical weather prediction, finite element analysis, computational fluid dynamics, computational physics and computational chemistry. It is one of the most popular languages in the area of high-performance computing and is the language used for programs that benchmark and rank the world's fastest supercomputers.
Only the above paragraph is probably not enough to describe the importance of FORTRAN language on engineering and scientific world. Literally, thousands lines of FORTRAN code have been written the last 50+ years from several developers throughout the world. And, now, the big question is: why not take advantage of the code already written in FORTRAN and use it from Excel/VBA? Is it possible to do that?
Well, I have some good news, the answer is YES! So, in this post I will try to provide you some insights about how to do it. In short, the idea is to build a Dynamic-link library (DLL) file that will include the necessary FORTRAN functions and subs, and, then, call these functions/subs (DLL file) from VBA.
FORTRAN Code
The first step on this tutorial is to build the DLL file. I used the FORTRAN code that you will find below; the FRICTIONFACTOR function is actually a FORTRAN version of an old VBA function that I developed some years ago. By the way, sorry for the uppercase in the code, but it is an old habit that I acquired when I was writing the FORTRAN code for my M.Sc. thesis. FUNCTION FRICTIONFACTOR (ROUGHNESS, DIAMETER, VELOCITY,VISCOSITY) !DEC$ ATTRIBUTES DLLEXPORT:: FRICTIONFACTOR
!------------------------------------------------------------------------ ----- !Calculates the friction factor of a pipe using Churchill's equation (1977). !This equation is valid for all types of flows (from laminar to turbulent). ! !Written by: Christos Samaras !Date: 21/03/2014 !e-mail: xristos.samaras@gmail.com !site: http://www.myengineeringworld.net !------------------------------------------------------------------------ -----
IMPLICIT NONE
!Declaring the necessary variables. REAL*8:: FRICTIONFACTOR,ROUGHNESS, DIAMETER, VELOCITY, VISCOSITY ,REYNOLDS, A, B, C, D
!--------------------------------------------------------------------- !Receives as input a one-dimensional array and it doubles tis values. ! !Written by: Christos Samaras !Date: 23/03/2014 !e-mail: xristos.samaras@gmail.com !site: http://www.myengineeringworld.net !---------------------------------------------------------------------
IMPLICIT NONE
!Declaring the necessary variables. INTEGER*4, INTENT(IN) :: ELEMENTS INTEGER*4, INTENT(IN) :: INARRAY(ELEMENTS) INTEGER*4, INTENT(OUT) :: OUTARRAY(ELEMENTS) INTEGER*4:: I
!Loop through all the elements of the array and double their value. DO I = 1,ELEMENTS OUTARRAY(I) = 2*INARRAY(I) ENDDO
RETURN
END
Important notes
1. In order to build the DLL file I used the old Compaq Visual Fortran (version 6.6) compiler. I am sure that you can find a much more recent compiler (for example an Intel Fortran Compiler).
2. Be careful of the attributes required for the DLL export, otherwise the FORTRAN functions/subs will not be visible from VBA: !DEC$ ATTRIBUTES DLLEXPORT:: FRICTIONFACTOR !DEC$ ATTRIBUTES DLLEXPORT:: DOUBLEARRAY The above lines might be slightly different for your compiler, but in any case must be included in the code (as a comment).
3. Be aware of DLL dependencies. If the DLL file is going to be used in other computers (that havent the same FORTRAN compiler installed), ensure that is independent. For example, to achieve this in Compaq Visual Fortran I had to go to Project -> Settings -> Fortran tab -> select Libraries from the dropdown menu Category, select the Single-Threaded from the Use run time library dropdown menu, and, finally, press the OK button (see the picture below). Otherwise, the DLL file that the compiler built required the MSVCRTD.dll file in order to run. You can check all the DLL dependencies using a great freeware tool called Dependency Walker.
VBA code
And here is the VBA code that calls the compiled FORTRAN code from the MySamble.dll file. Option Explicit Option Base 1
'--------------------------------------------------------------------------- 'This module contains two examples of calling a FORTRAN dll from Excel/VBA. 'The first one uses a FORTRAN function straight from the worksheet, 'while the second one calls a FORTRAN sub from a VBA sub.
'Declaring the function and the sub from dll file. 'NOTE: if the dll file is NOT in the same folder with the workbook, use its full path instead. Example: 'Public Declare Function FRICTIONFACTOR Lib "C:\Users\Christos\Desktop\MySample.dll" Public Declare Function FRICTIONFACTOR Lib "MySample.dll" _ (ROUGHNESS As Double, _ DIAMETER As Double, _ VELOCITY As Double, _ VISCOSITY As Double) As Double
Public Declare Sub DOUBLEARRAY Lib "MySample.dll" _ (ELEMENTS As Long, _ INARRAY As Long, _ OUTARRAY As Long)
Sub CallDoubleArray()
'Declaring the necessary variables. Dim i As Long Dim LastRow As Long Dim ArrayIn() As Long Dim ArrayOut() As Long
'Activate the Sub sheet and find the last row. With Sheets("Sub") .Activate LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row End With
'If there is at least one value proceed. If LastRow >= 4 Then
'Resize the arrays. ReDim ArrayIn(1 To LastRow - 3) ReDim ArrayOut(1 To LastRow - 3)
'Populate the input array. For i = 4 To LastRow ArrayIn(i - 3) = ActiveSheet.Range("B" & i) Next i
'Call the FORTRAN Sub. Call DOUBLEARRAY(LastRow - 3, ArrayIn(1), ArrayOut(1))
'Pass the results back into sheet. For i = 4 To LastRow ActiveSheet.Range("D" & i) = ArrayOut(i - 3) Next i
Else
'Empty column, inform the user. MsgBox "Please enter at least one value on B column and retry!", vbExclamation, "No data" ActiveSheet.Range("B4").Select
End If
End Sub
Important notes
1. It is essential to call the function/sub included on the DLL file using the correct data type. Here is a short list of FORTRAN data types, along with the corresponding VBA/VB 6.0 data types.
FORTRAN data types VBA/Visual Basic data types ---------------------- -------------------------------- INTEGER*2 Integer INTEGER*4 Long REAL Single REAL*4 Single DOUBLE PRECISION Double REAL*8 Double LOGICAL*2 Integer LOGICAL*4 Long CHARACTER*n String*n (Passed ByVal)
2. Note the use of Option Base 1 in the beginning of the code. Contrary to VBA, arrays in FORTRAN are NOT zero-based, so we use this expression in order to avoid array sizing problems between the two languages.
3. In order to avoid calling the DLL file using its full path I used the following workbook open event, which changes the current directory to the folder where the workbook is located: Private Sub Workbook_Open()
If the DLL file is NOT in the same folder with the workbook, use its full path. For example: Public Declare Function FRICTIONFACTOR Lib "C:\Users\Christos\Desktop\MySample.dll"
4. The second example (with the sub), although might looks trivial, it actually shows you how to transfer arrays between VBA and FORTRAN. Note that in the following line we use the first element of each array: Call DOUBLEARRAY(LastRow - 3, ArrayIn(1), ArrayOut(1))
Epilogue
FORTRAN is not a dead/outdated programming language. Its still being used by many developers/scientists/engineers. My suggestion is to take advantage of the code already written in FORTRAN and dont re-inventing the wheel. I know that the mixing of FORTRAN and VBA is probably a little advanced topic, but the above example, along with the side notes will help you overcome many of the obstacles that you will find on your way.