The MemoryFile is one of ASNA Visual RPG’s (AVR) most frequently used objects. The MemoryFile is a programming interface that wraps .NET’s System.Data.DataSet. It allows rows to be written to an underlying DataTable with the RPG Write operation. The MemoryFile’s resulting DataSet and single DataTable are often used to bind data to UI interface elements such as GridViews and DataGridViews.

There are two ways to describe a MemoryFile in AVR:

Externally Described MemoryFiles

Externally described MemoryFiles have a field layout (the table schema) that is defined by an existing physical or logical file. 

Figure 1a. Externally described memory file

Figure 1a above shows how to externally describe a memory file. In this case, the memory file has 100% the same fields as the field defined in the FileDesc keyword (in this case, Examples/CMastNewL2). At compile time, AVR copies the specified file’s description to the MemoryFile. Figure 1a shows a typical use of the MemoryFile. 

MemoryFiles can be written to like a physical or logical file and have Open() and Close() methods. However, MemoryFiles are not really files (ie, they don’t have a handle that ties them to a underlying database platform) and don’t need to be explicitly opened or closed. The ImpOpen keyword can be used to require the use of Open() and Close() methods with a MemoryFile but its use is superfluous and just adds noise to your code. Best practice: don’t include the ImpOpen keyword with MemoryFiles and don’t worry about opening or closing them. They are “open” by default (which for a MemoryFile means they are instanced by default) and “closed” (ie, reclaimed by the garbage collector) when they go out of scope in your program. 

One of the reasons to use an externally described MemoryFile is when you need to store the contents of one or more records read from a physical or logical file. The fragment below shows this is in action:

Figure 1b. A typical use of an externally described MemoryFile.

Program Described MemoryFiles

A program described MemoryFile has its record format layout described inline–in the program. While “program described” anything in a traditional RPG program is often looked down on, program described MemoryFiles in AVR are very popular (you’ll probably find yourself using more of them than using externally described MemoryFiles) and more closely persist the traditional RPG program-described subfile idiom.

Figure 2a. Program described memory file

Figure 2a above shows how to program describe a MemoryFile. In this case, the memory file has three fields. The name and type for each field must be explicitly provided. With an externally described MemoryFile, it’s quite challenging to add a field to the MemoryFile schema at runtime. However, with the program described technique shown above, it’s easy to create an arbitrary schema. For nearly all tasks related to populating UI elements with a MemoryFile, you’ll want to use a program described MemoryFile. Its superior flexibility over the externally described memory file make the extra typing required worthwhile.

With a program described MemoryFile, at compile time AVR copies the specified file’s description to the MemoryFile. Figure 2b shows how to write to a MemoryFile. Sometimes, though, rather than dealing with AVR’s higher level ways to write to the MemoryFile, you also want to work at a lower level with the MemoryFile’s underlying DataGate. The routines ListColumnNamesAndType and ListCoumnValue show how to read a DataGate’s data.

Figure 2b. Example program writing to a MemoryFile

The example above uses these keywords with the MemoryFile:

The DataTable can have zero or more records in it, so .NET developers often use the DataSet and its DataTable(s) as an in-memory data store. For example, the following console application shows a way to instance a MemoryFile and write ten records (this simple code includes no error handling and assumes there are at least ten records in the CMastNewL2 file) to the MemoryFile:

A quick note about Figure 2b: Figure 2b uses a Console application project type. If you haven’t yet used a console application, consider adding it to your .NET kitbag. It is perfect for testing things. It removes all unnecessary forms and other environmental things and lets you focus simply on the code. If you’re new to console applications, they do have what appears to be a minor inconvenience. A console app needs a shared subroutine named “Main”; this convention determines the entry point for the app. The apparently inconvenient part is that because Main is shared, other members of its parent class must also be shared. To avoid this, I always code a second class (usually named Test), add a public Run method, and then instance the class and run its Run() method with this single line of code:

MemoryFile Rules of Thumb