OML for the complete beginner, Lesson 6

Commands, continued

Last time, I covered the main commands you can use to add, change, and remove data from a MARC record, and perform some basic OCLC actions on a record. However, there is much, much more that macro commands can do.


Now that you're all ready to use the commands you used last time, what do you do when you want a macro to grab the contents of whatever field the cursor is currently in, so you know what row number to feed to CS.GetFieldLine?

  Sub Main
    Dim CS As Object
    Set CS = CreateObject("Connex.Client")

    CurrentRow% = CS.CursorRow
    CS.CursorRow = 3
  End Sub

The first CursorRow command finds the row number of the field the cursor is in and stores that number in CurrentRow%. The second CursorRow command moves the cursor to the third field in the record. (Remember, since Connexion is field-based rather than row-based, these numbers refer to the field number, counted from the top of the record, regardless of whether or not any fields wrap onto multiple lines.) If you'd rather check on or change how many characters to the right the cursor is in a field, the corresponding command is the aptly-named CS.CursorColumn. Note that the response represents the character to the right of the cursor. If the cursor is at the beginning of the tag in a field, that is column #1. The indicators are columns #4 and #5. The beginning of the field data is column #6. One odd quirk caused by Connexion's division of the tag, each indicator, and the field data into cells is if the cursor is at the end of the tag cell, after the last number in the tag, then it is actually at column #4, because the next character after the cursor is the first indicator position.

The CS.CursorPosition command gets around this problem by assigning different numbers to the beginning and end of each cell, but if there is no data in a cell--such as for blank indicators--then only the beginning position is numbered. This means the results can vary widely depending on the value of the indicators. Therefore, when writing macros that check or set the cursor column, it is best to try to always use CS.CursorColumn and only use CS.CursorPosition when absolutely necessary. Recorded macros always use CS.CursorPosition, but if you find that a recorded macro doesn't move the cursor properly, or if you want to modify a recorded macro, it's probably best to change it to use CS.CursorColumn instead.


With Connexion, it is possible to "control" headings, linking them directly to their authority file records, if any exist. You can control headings manually, but you can also do it automatically with a macro command--which may come in handy if you've been giving CS.AddField and CS.SetField a workout.

  bool = CS.AddField(99,"650 0Audiobooks.")
  bool = CS.ControlHeadingsAll

This macro fragment adds a 650 of "Audiobooks," then attempts to control all uncontrolled headings in the record. Those that can be automatically controlled will be, and those that can't will be left alone. If one or more headings in the record fall into that second category, then CS.ControlHeadingsAll will return a value of FALSE, just as if the command had completely failed to execute.

If you want to edit a controlled heading, you must first uncontrol it. This can also be done via a macro. CS.UncontrolHeading uncontrols the heading where the cursor is currently located. CS.UncontrolAll uncontrols all headings in the record.


Sometimes, when writing a macro, it can be very important to know what the OCLC number is, whether your library already owns a particular title, whether a record has been successfully validated, and so forth. For these and other questions, there is CS.QueryRecordStatus.

  bool = CS.QueryRecordStatus("NUM", OCLCNum$)
  bool = CS.QueryRecordStatus("HELD", IsHeld$)
  bool = CS.QueryRecordStatus("VAL", IsValidated$)
  bool = CS.QueryRecordStatus("MYSTATUS", MyStatus$)

After running through those commands, OCLCNum$ would contain the OCLC number. IsHeld$ would contain "Y" if the status bar says "Held by" and your OCLC symbol and "N" if not. IsValidated$ would contain a "c" if the record had been completely validated, an "f" if validation had failed, or a "-" if the record had not been validated at all. And finally, MyStatus$ would contain the full text of the MyStatus field.

(Note that you can also get the OCLC number via CS.GetFixedField, by using "OCLC" as the fixed field to pull from. In fact, that way is probably easier to remember than considering the OCLC number to be a "status." The primary difference is in how the commands handle records with an OCLC number of "NEW"; CS.GetFixedField returns "NEW", CS.QueryRecordStatus returns "-1".)

Speaking of My Status, when a macro has touched a record, it can be useful to change the record's status to reflect that. As you may have guessed, there's a command for that, too. Two of them, actually, since Connexion has two types of record statuses.

  bool = CS.SetMyStatus("949 field added by macro")
  bool = CS.SetWorkflowStatus("In Process")

The first of those adds "949 field added by macro" to the record's My Status field, replacing anything that might already be in that field. The second changes the record's workflow status from whatever it was to "In Process". (Valid values are "Completed", "In Process", "In Review", and "New.")


CS.ItemType simply returns a number that indicates what type of window is on top in the main Connexion window, such as a bibliographic record, an authority record, a list of records, and so forth. The complete set of possible values is in the Connexion help file, but those you will probably use the most in macros include 0 (Online bibliographic record), 1 (Online bibliographic save file record), 6 (WorldCat brief list), 7 (Online save file list), 17 (Local bibliographic save file record), and 21 (Local bibliographic save file list).

  WindowType% = CS.ItemType
  Msgbox CStr(WindowType%)

Some commands can only be run when Connexion is connected to OCLC. If you try to run them when you aren't online, you may get all sorts of strange errors (if anything happens at all). The remedy for this is to check with CS.IsOnline.

  bool = CS.IsOnline

This command returns TRUE (or -1) if you are currently online and connected to OCLC, and FALSE (or 0) if you aren't. It's that simple!

If you get to a point in a macro where you discover you aren't online and wish you were, or are already online and wish you weren't, there are two commands to handle those situations: CS.Logon and CS.Logoff.

  bool = CS.Logon(Authorization$, Password$, "")
  CS.Logoff

As you can see, you need a bit more information to log on than to log off, but each is relatively self-explanatory. One piece to note is that if you leave the authorization and password blank (""), then Connexion will automatically use the authorization and password from your default logon. If you only use one authorization, then you can always leave those fields blank and save yourself a few keystrokes.


When a macro is all finished with a record, it's often time to close the window and move on to something else. A pair of commands will take care of all that work for you.

  bool = CS.CloseRecord(TRUE)
  CS.CloseList

Each command does exactly what it looks like it would: CS.CloseRecord closes the window of the uppermost open record, and CS.CloseList closes the window of the uppermost open list (such as a search results list or a browse list). The "TRUE" after CS.CloseRecord indicates that the record should automatically be saved before it is closed; FALSE indicates that the record should just be closed without being saved first. (This is the same thing as answering Yes or No to the prompt "The record has been changed. Do you want to save it before proceeding?" when you are manually closing records.)


If you want your macro to be able to automatically look for records in OCLC (for example, if you write a macro that takes in a list of OCLC numbers, searches for each, and deletes your holdings), then you obviously need to be able to search WorldCat.

  NumRecords% = CS.Search("WC", "au twain and ti tom and ti sawyer")

What that example does is search WorldCat for the specified search terms. Connexion opens a list displaying the results, exactly the same as if you had manually entered the search, and sends the macro the number of records in the list.

CS.Search can also search your online or local bibliographic save files--using the "BS" (online) or "BL" (local) database codes--authority files, constant data files, or review records. The helpfile contains a long list of possible database codes and what index codes are valid for each.

If you've gotten a list instead of a single record with CS.Search, in order to find the exact record you're looking for, you could have the macro open each record in turn (more on how to do that in later lessons), or you could use CS.SearchList.

  NumRecordsDisplayed% = CS.Search("WC", "au twain and ti tom and ti sawyer/bks/2001-2004")
  NumRecordsSelected% = CS.SearchList("HarperCollins", "Description", FALSE)

The first command searches WorldCat for recent Tom Sawyer books by Twain, and sets NumRecordsInList% to the total number of records displayed in the resulting list. Assuming it is more than one, the second line searches for any of those that have the word "Harper" anywhere in the Description column. It will also match "harper", "HarperCollins", "HarperTrophy", "HarperSanFrancisco", and so forth. All matching records are automatically selected, so that if you then open a record, you can use the Forward button to jump directly to the next selected record.


If your macro can't automatically find a record, then it can automatically create one instead.

  bool = CS.OpenWorkform("bks")
  bool = CS.OpenWorkform("apn")

The first line of this example opens a new Books workform for editing. The second line opens a new Personal Name authority workform for editing. The bibliographic workforms all use the same three-letter codes that OCLC always uses. The codes for authority workforms are the similar to the two-letter authority scan index codes, preceded by "a", thus apn, acr, etc.; the complete list is in the Connexion help file.

If your macro found a record that is similar, but not quite close enough to use, you can have it automatically derive a new record.

  bool = CS.DeriveNewRecord(TRUE)

This example derives a new record and also carries over the fixed field values. Using FALSE would only carry over the variable fields instead.

Next time, program flow control...


Return to Lesson #5.
Return to Main page.

Copyright 2004, Joel A. Hahn
Sponsored and endorsed by OCLC Online Computer Library Center, Inc.