Reading data of different types from a data file with multiple lines and headers for each line

Okay here’s an attempt at a reasonably close approximation to what I would try:

Start with a csv file which has 400 columns, each of which has the name of the parameter as the header, and 1 row, which has the values for each parameter. At this point your parsing step is as simple as:

julia> using CSV, DataFrames

julia> input_data = Tables.rowtable(CSV.File("out.csv", pool = false))
1-element Vector{NamedTuple{(:location, :elevation, :latitude, :longitude, :year), Tuple{String, Int64, Float64, Float64, Int64}}}:
 (location = "Toowoomba", elevation = 598, latitude = -27.55, longitude = 151.95, year = 2010)

The result is a vector of NamedTuples (with a length of one, as there’s only one row). NamedTuples work well with the macros in Parameters.jl,

Next, define a struct that holds your parameters:

julia> using Parameters

julia> @with_kw struct ModelParameters
           location::String
           elevation::Int64
           latitude::Float64
           longitude::Float64
           year::Int64
       end
ModelParameters

Note that this is still quite cumbersome if the struct has 400 fields (I also don’t know what the compiler will think about this, as I’ve never encountered such a large struct, but I guess performance won’t matter when just passing the parameters around). There might be a way to group things which makes intuitve sense, but that will depend on your application - as an example, you might have a field position which is a Vector{Float64} that holds elevation, longitude, latitude instead of three separate fields.

With your struct defined and the data from VBA read into a NamedTuple, you can then create a ModelParameters instance to collect the parameters and pass them into your solver:

julia> parameters = ModelParameters(input_data[1]...)
ModelParameters
  location: String "Toowoomba"
  elevation: Int64 598
  latitude: Float64 -27.55
  longitude: Float64 151.95
  year: Int64 2010

This parameters object can then be passed into the solver (so your solver should be defined as solve_ode(parameters::ModelParameters). Then at the start of your solve_ode function you do:

julia> @unpack location, elevation, latitude, longitude, year = parameters
ModelParameters
  location: String "Toowoomba"
  elevation: Int64 598
  latitude: Float64 -27.55
  longitude: Float64 151.95
  year: Int64 2010

julia> location
"Toowoomba"

and all your variables are defined.