Class: Xls2odat

Inherits:
Object
  • Object
show all
Defined in:
lib/xls2odat.rb

Overview

Convert command from oddb mutations xls file to text file.

xls2odat converts one or more XLS files to flat files so they can be imported to a drugstore software or a pharmacy software in Switzerland.

Authors

Masaomi Hatakeyama ([email protected])

Version

1.1.7 2010-10-22 commit

Copyright

Copyright © ywesee GmbH, 2010. All rights reserved.

License

GPLv2.0 Compliance

Source

scm.ywesee.com/?p=xls2odat/.git;a=summary

Constant Summary collapse

VERSION =
'1.1.7'
COLUMNS =
[ :filenr, :seqnr, :field_name, :T, :L, :description, :bemerkung ]
FIELDS =
[0.0, 0.0, "Field name", "T", "L", "Description", "Bemerkung"]

Instance Method Summary collapse

Constructor Details

#initializeXls2odat

Returns a new instance of Xls2odat.



24
25
26
27
28
29
30
31
32
33
# File 'lib/xls2odat.rb', line 24

def initialize
  @conf          = []  # @conf[config No][file index, column A][index, column B] == config value, column H
  @out_filename  = []  # output file name list 
  @out_data      = {}  # key: @out_filename, output data list
  @pharmacode    = 0   # pharmacode (be incremented)
  @pharmacode_increment = true  # flag when @pharmacode is increment
  @iterate_count = 0   # count variable for iteration
  @max_reclen    = {}  # key: @out_filename, value: length of logest record (bytes)
  @odat_version  = 0   # odat version: related to output file names and log file
end

Instance Method Details

#outputObject

Output data

output @out_data list into @out_filename files

return

none



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/xls2odat.rb', line 165

def output

  @out_filename.each do |filename|
    open(filename, "w") do |out|
      max_reclen = 0
      @out_data[filename].each do |line|
        line_str = line.join("|").to_s + "\n"
        # search the longest record
        max_reclen = line_str.size if line_str.size > max_reclen
        out.print line_str
      end
      @max_reclen[filename] = max_reclen
    end
  end

  if @odat_version == 2
    output_log
  end
end

#parse_data(target, confnr = 0) ⇒ Object

Parsing data

Parsing the data files and the data converted are set in @out_data list

target

data file path (String)

confnr

configuration number (Integer)

return

none



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/xls2odat.rb', line 107

def parse_data(target, confnr=0)
  # read_config must be run before this method
  if @conf.length == 0
    raise "Config file has not been read yet."
  elsif @conf[confnr] == nil
    raise "No config information for Config. No.#{confnr}. Check #{target}."
  end

  # open data file
  Spreadsheet.client_encoding = 'UTF-8'
  tbook = Spreadsheet.open(target)

  # initialize 
  @phamacode = 0

  # parse data
  tbook.worksheet(0).each_with_index do |row,ri|
    # save prefix
    @prefix = cell("A", row).strip if cell("A", row) =~ /^\s+.+/ and row.to_a.delete_if{|x| x == nil}.length == 1
    if ri > 0 and cell("A", row) != "" and row.to_a.delete_if{|x| x == nil}.length > 5 # skip the title line in xls file
      @pharmacode_increment = false # this will be changed in analyzer method
      # output separately in each output file
      @out_filename.each do |filename|
        filenr         = filename.delete("H").delete("s").to_i
        config         = @conf[confnr][filenr]
        iterate_length = 1

        # check iteration
        iterate_config = config.grep(/,/)
        if iterate_config.length > 0
          iterate_flag   = true
          iterate_length = iterate_config[0].split(",").length
        end

        iterate_length.times do |i|
          @iterate_count = i  # @iterate_count would be used in analyzer method

          # buffer one line
          line_buffer = []
          config.slice(1..-1).each do |conf|
            line_buffer << analyzer(conf, row, target)
          end

          # output
          @out_data[filename] << line_buffer
        end # iterate_length.times
      end # @out_filename.each

      @pharmacode += 1 if @pharmacode_increment == true
    end # if ri > 0
  end # tbook.worksheet(0).each_with_index
end

#read_config(target) ⇒ Object

Reading a configuration file

This method reads a configuratin file (.xls) and sets the information in @conf variable

target

config file path (String)

return

none



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/xls2odat.rb', line 43

def read_config(target)
  # read file
  Spreadsheet.client_encoding = 'UTF-8'
  tbook = Spreadsheet.open(target)
  fields = tbook.worksheet(0).row(0).to_a
  new_columns = fields[FIELDS.size..fields.size-1].delete_if{|x| x == nil}

  # check file
  if fields[0..6] != FIELDS
    raise "Config file format is wrong (#{fields.join(", ").to_s})"
  elsif new_columns.size == 0 
    raise "No config information in #{target}"
  end

  # output file name list
  outfilelist = tbook.worksheet(0).column(0).to_a.uniq.delete_if{|x| x == nil}.map{|x| "%02d" % x.to_i}
  outfilelist.shift # delete the first value corresponding to the first line date in xls file
  # check odat version
  if outfilelist.include?("06") or outfilelist.include?("07")
    @out_filename = outfilelist.map{|x| "s" + x}
    @odat_version = 3
  else
    @out_filename = outfilelist.map{|x| "H" + x}
    @odat_version = 2
  end
  # initialize output data list
  @out_filename.each do |filename|
    @out_data[filename] = Array.new
  end

  # initialize @conf format
  @conf.fill(0, new_columns.length){[]}

  # import data and set it in @conf
  tbook.worksheet(0).select{|r| r[0] != nil}.each do |row|
    filenr = row[column_s(:filenr)].to_i
    seqnr  = row[column_s(:seqnr)].to_i

    new_columns.length.times do |i|
      @conf[i][filenr] = [] if @conf[i][filenr] == nil
      value = row[FIELDS.size+i]
      @conf[i][filenr][seqnr] = if value.class == Float
                                  value.to_i
                                else
                                  value
                                end
    end
  end

  # there is no judge statement for checking the number of iterations.
  # in the case that there is more than two informations of iteration, 
  # it should be checked here
  # if the numbers of iterations (numbers of ",") are same or not.
end