I spent a few hours this morning trying to use Piers Harding’s SAP/Rfc library for Ruby to read a table from SAP. I found several examples using other languages (Perl, VBscript, PHP, etc.), but the only Ruby example I could find reads the entire table. Figuring out how to load the “options” took some trial and error.

The idea of this example is to read the “LQUA” table in SAP which stores information about where to find a particular material in the warehouse. The whole thing is wrapped up in its own model so it can be easily called elsewhere in my Rails app:

Which yields a handy data set containing all the locations and available quantity for the DigiTech Vocalist 300 in the warehouse. This will be used as part of my new scan gun application which directs the shipping department to the various storage bins for picking large orders.

UPDATE: It seems the preferred approach is to use the new SAP Netweaver RFC library (sapnwrfc.rb). This changes the code sample a bit…

The trickiest part was figuring out the correct syntax for the OPTIONS and FIELDS. Pier’s documentation hints at the correct format (look under the heading ‘A Closer Look At Handling Parameters’), but I had to dig in to the table structures within the function in SAP to figure out that it was expecting ‘TEXT’ and ‘FIELDNAME’. So, if you’re using some other function, then explore the table structures to learn what the function expects to see.

Let’s say you have a series of numbers (1,2,3,4,5…500+) and you need to convert them to letters like A,B,C,D…AA…ZZ (think Excel column headers.)

I searched and searched to find a built-in way of doing this with Ruby, but I couldn’t find it. So, I tried to write my own:

def number_to_letter(n=1)
n.to_i.to_s(27).tr("0-9a-q", "A-Z")
end

That works great except that 1=B instead of A, so all of AA,AB,AC…AZ doesn’t work. I tried all sorts of different ideas based on the one above. Then, I stumbled on: succ.

For an Integer, it makes a lot sense: 1.succ = 2, and so on (returns the next integer). But, it also does exactly what I need for strings: “A”.succ = “B” and “Z”.succ = “AA”. So, rather than converting numbers to letters, I ended up with a block like this: