Error during data conversion from Vensim (.vpmx) to Excel
quaquel opened this issue · 0 comments
quaquel commented
Discussed in #272
Originally posted by Condor323 June 6, 2023
Dear reader,
My goal is to extract instances and the values of constants in a certain Vensim model and convert them to csv (Excel). When running the code i come across a type error which i cannot solve. I have already tried looking and making adjustments in the ema and ctypes libraries but to no avail. One adjustment from the original code was changing the extraction format for the vensim data from the vpm format in the code to vpmx.
I share the error and de full code under this post.
error
TypeError Traceback (most recent call last)
<ipython-input-8-6cf498b0d2f7> in <module>
13 typeNr = var_type
14 print(var_type)
---> 15 varNames = get_varnames(filter=b'*', vartype=var_type) #
16 for varName in varNames: # per name, look in to their attributes
17
~\anaconda31\lib\site-packages\ema_workbench\connectors\vensimDLLwrapper.py in get_varnames(filter, vartype)
384 filter = ctypes.c_char_p(filter) # @ReservedAssignment
385 vartype = ctypes.c_int(vartype)
--> 386 buf = ctypes.create_string_buffer("", 512)
387 maxBuf = ctypes.c_int(512)
388
~\anaconda31\lib\ctypes\__init__.py in create_string_buffer(init, size)
63 buf = buftype()
64 return buf
---> 65 raise TypeError(init)
66
67 def c_buffer(init, size=None):
TypeError:
code
'''
Created on 24 June 2013
This script intends to sort the Vensim variables to a csv file.
@author: Willem L. Auping
'''
import csv
from ema_workbench.connectors.vensimDLLwrapper import get_varnames, get_varattrib
from ema_workbench.connectors.vensim import load_model
vensimRootName = r'C:\Users\coene\OneDrive\Documenten\EPA\Y2Q3\Capita selecta\project map'
vensimFileName = r'\20160323 Global Energy model - Climate policies' # The name of the vensim model of interest
vensimExtension = r'.vpmx'
csvFileName = vensimFileName+'.csv' # The name of the csv file
csvArray = ['Nr', 'Name', 'Equation', 'Unit', 'Comments', 'Type', 'Float', 'Int'] # The order of the elements in the array of every row
firstLine = ['Global Energy model data'] # The first lines of the csv file
secondLine = ['Model title',vensimFileName]
thirdLine = ['Time unit','Year'] # Write here the time unit of the model (or can it be found in the model?)
blank = ''
lineNumber = 1
attributeNames = ['Units', 'Comment', 'Equation', 'Causes', 'Uses', 'Initial causes',
'Active causes', 'Subscripts', 'Combination Subscripts', 'Minimum value',
'Maximum value', 'Range', 'Variable type', 'Main group']
attributes = range(len(attributeNames))
attributesInterest = [3, 1, 2, 12]
varTypeNames = ['All', 'Levels', 'Auxiliary', 'Data', 'Initial', 'Constant', 'Lookup',
'Group', 'Subscript Ranges', 'Constraint', 'Test Input', 'Time Base',
'Gaming']
varTypes = range(len(varTypeNames))
var_types = [1,2,3,4,5,6]
print('Vensim file: {}{}{}'.format(vensimRootName, vensimFileName, vensimExtension))
print('CSV file: {}{}'.format(vensimRootName, csvFileName))
print('Converting starts...')
load_model(vensimRootName + vensimFileName + vensimExtension)
with open (vensimRootName + csvFileName, 'w') as f:
writer = csv.writer(f)
writer.writerow(firstLine) # The first lines are written
writer.writerow(secondLine)
writer.writerow(thirdLine)
writer.writerow(blank)
writer.writerow(csvArray)
for var_type in var_types: # Now get the variables per type
type = varTypeNames[var_type]
typeNr = var_type
print(var_type)
varNames = get_varnames(filter=b'*', vartype=var_type) #
for varName in varNames: # per name, look in to their attributes
csvArray[0]=lineNumber # setup the line which needs to go to the csv
csvArray[1]=varName
csvArray[5]=varTypeNames[var_type]
for attributeInterest in attributesInterest: # put the attributes also in the line, in the right place
attribute = get_varattrib(varName, attributeInterest)
if attribute == []:
attribute = [blank]
if attributeInterest == 1: # Unit
Unit = attribute[0]
csvArray[3] = Unit
elif attributeInterest == 2: # Comment
csvArray[4] = attribute[0]
elif attributeInterest == 3: # Equation
equation = attribute[0]
equation = equation.lstrip(varName)
equation = equation.replace(r'\\n','')
equation = equation.replace(r'\\t','')
equation = equation.replace(r'\n','')
equation = equation.replace(r'\t','')
equation = equation.replace(r' ','')
equation = equation.lstrip('=')
equation = equation.lstrip(r' ')
csvArray[2] = equation
if typeNr == 4: # if type is Initial
csvArray[6] = 'x' # The value for the 'Float' column is 'x'
csvArray[7] = blank # The 'Int' column is empty
elif typeNr == 5: # if type is Constant
if varName[0:5] == 'Delay':
csvArray[6] = blank
csvArray[7] = ', integer=True'
elif varName[0:6] == 'Switch':
csvArray[6] = blank
csvArray[7] = ', integer=True'
else:
csvArray[6] = 'x'
csvArray[7] = blank
else:
csvArray[6] = blank
csvArray[7] = blank
# print csvArray
writer.writerow(csvArray)
# print varTypes
lineNumber += 1
print('Converting ended.')