'MacroName:CopyFields 'MacroDescription:Copies several fields without requiring the ' cursor to be placed in any certain position. ' ' This macro was written by Walter F. Nickeson, ' University of Rochester, Rochester, NY ' wnickeson@library.rochester.edu ' ' Last updated: 24 September 2007. ' Check for the latest versions of this and my other macros at ' http://docushare.lib.rochester.edu/docushare/dsweb/View/Collection-2556 ' Please e-mail me with bug reports or to suggest improvements. ' ' Works in Connexion client 2.10. ' '*************************************************************** ' How it works: This macro copies contiguous variable fields ' from a record in the Client without your having to worry about ' precise cursor placement. First, have a bibliographic or ' authority record open ready to paste into. (The target record ' doesn't have to be on top, or visible. You can also paste ' fields into the same record from which you copied them, ' although if you want to simply copy one field--e.g., to copy ' the 100 to make into a 600--my "DuplicateField" macro is ' better. Furthermore, you can have as many open records or ' lists as you need--the macro ignores list displays.) In the ' record from which you are copying, click anywhere in the first ' field to copy, and extend the selection by dragging straight ' down across all the fields you wish to include in the copy, ' ending anywhere in the cell containing the last field to be ' copied. (You can also select by dragging backward, or up.) You ' don't have to click at the beginning of the tag in the first ' field, and end the selection with the last character in the ' last field, or vice-versa. The macro copies the whole of the ' fields in which the selection begins and ends (even though ' they may be only partially highlighted), and all fields in ' between, and then shows all the other open records of the same ' kind for you to choose in which one to paste. If you select ' only part of a single field, the whole field will be copied. ' ' The macro looks at the text that has been selected, figures ' out how many fields it spans, gets those fields, and stores ' them in an array. It uses the "GetField" command in order to ' include text not selected in the lines at the beginning and ' end of the selection block. Since special characters acquired ' with that command are lost by the Windows clipboard, the ' "AddField" command is used instead to paste the copied data. ' Finally, the macro displays, one at a time, all the ' appropriate records (unless they are tiled; but the macro ' still lets you know which record is the target) until ' instructed to stop at one and add the copied fields. '*************************************************************** Option Explicit Sub Main Dim CS As Object Set CS = CreateObject("Connex.Client") Dim CopySelection$ : CopySelection$ = "" Dim EndOfField$ : EndOfField$ = Chr$( 013 ) & Chr$( 010 ) Dim FieldRetrieved$ Dim Fields$ Dim FirstTag$ Dim OCLCNumberFrom$ Dim OCLCNumberTo$ Dim RecordKind$ Dim SelectedText$ Dim WindowTitle$ Dim Answer% Dim BeginningRow% Dim CountOfWindows% : CountOfWindows% = 0 Dim CountRecs% : CountRecs% = 0 Dim CurrentRow% Dim Difference% Dim EndOfFieldCount% : EndOfFieldCount% = 0 Dim EndOfFieldFound% : EndOfFieldFound% = 0 Dim Start% : Start% = 1 Dim TypeOfWindow% Dim WindowId% Dim a, b, c, d, e, f, g : b = 0 Dim SameRec : SameRec = FALSE Dim SelectedUp : SelectedUp = FALSE Dim FieldsCopied$() Dim SelectRecs() ' First, check to see that some text has been selected! If CS.GetSelectedText( SelectedText$ ) = FALSE Then MsgBox "Please select some fields to copy!", 64, "Macro needs a selection to copy" GoTo Done: End If ' If the selection has been made by dragging upward, the last ' characters will be the end-of-field marker (ASCII characters ' 013 + 010). In this case we must do some calculations to ' figure out in which row is the end of the selection If Right$( SelectedText$, 2 ) = EndOfField$ Then SelectedUp = TRUE ' Get the OCLC number of the source record; this will be used ' later to aid in choosing the correct record in which to paste ' the copied field(s) CurrentRow% = CS.CursorRow Clipboard.Clear CS.CopyControlNumber OCLCNumberFrom$ = Clipboard.GetText() ' Determine whether this is a bibliographic or authority record, ' so the same sort of record will be displayed to paste into; ' it's unlikely that several fields would be copied into a ' record of a different kind TypeOfWindow% = CS.ItemType Select Case TypeOfWindow% Case 0 To 2, 17, 19 RecordKind$ = "B" Case 3 To 4, 14, 18, 20 RecordKind$ = "A" Case Else MsgBox "This macro only works in bibliographic and authority records! Exiting.", 64, "Macro finished" GoTo Done: End Select ' Then find the end-of-field markers within the selection to ' count how many fields have been included. The macro will also ' work with a selection made in a single field; in that case, it ' will copy the whole field Do EndOfFieldFound% = InStr( Start%, SelectedText$, EndOfField$ ) If EndOfFieldFound% > 0 Then Start% = EndOfFieldFound% + 1 EndOfFieldCount% = EndOfFieldCount% + 1 End If Loop Until EndOfFieldFound% = 0 If EndOfFieldCount% = 0 Then Fields$ = "field" Else Fields$ = "fields" End If ' The Client can tell where the end of the selection is by the ' cursor position, so by knowing how many end-of-field markers ' there are we can work backwards to find the row where the ' selection begins If SelectedUp = TRUE Then CurrentRow% = CurrentRow% + EndOfFieldCount% Difference% = CurrentRow% - EndOfFieldCount% BeginningRow% = Difference% ' Get each field within the selection and store it in an array. ' Although appending each field to a string variable and then ' sending that whole string to the Windows clipboard for pasting ' would be a simpler solution, that method can't handle special ' characters ReDim Preserve FieldsCopied$( EndOfFieldCount% ) For a = 0 To ( EndOfFieldCount% ) If CS.GetFieldLineUnicode( BeginningRow%, FieldRetrieved$) = FALSE Then MsgBox "Sorry, the macro failed to get a field.", 16, "Macro failed" GoTo Done: Else FieldsCopied$( a ) = FieldRetrieved$ End If BeginningRow% = BeginningRow% + 1 Next a ' Find a record to paste into. Cycle through all the open ' windows to find bibliographic or authority records, whichever ' matches the kind of record from which the fields were copied. ' Store their identification numbers in an array so they can be ' brought to the top, one by one, if necessary, to find the one ' in which to paste the copied field(s) CountOfWindows% = CS.WindowCount Do Until b = CountOfWindows% CS.SetTopWindow( b ) TypeOfWindow% = CS.ItemType Select Case TypeOfWindow% Case 0 To 2, 17, 19 If RecordKind$ = "B" Then ReDim Preserve SelectRecs( CountRecs% ) SelectRecs( CountRecs% ) = b CountRecs% = CountRecs% + 1 End If Case 3 To 4, 14, 18, 20 If RecordKind$ = "A" Then ReDim Preserve SelectRecs( CountRecs% ) SelectRecs( CountRecs% ) = b CountRecs% = CountRecs% + 1 End If End Select b = b + 1 Loop ' If no suitable record window is open, exit the macro If CountRecs% = 0 Then CS.SetTopWindow( CountOfWindows% ) MsgBox "No suitable record was found!", 48, "No record available" GoTo Done: End If ' Display the record(s) for consideration. First, capture the ' window title, and the OCLC control number, if any, to display ' in the dialog box that asks if the record displayed is the ' correct one into which to paste the field(s). This information ' is especially useful when the windows are tiled, as it's hard ' then to tell which record has the focus, or when working with ' two records for the same title For c = 0 To CountRecs% - 1 CS.SetTopWindow( SelectRecs( c ) ) TypeOfWindow% = CS.ItemType If CS.GetWindowTitle ( -1, WindowTitle$ ) = TRUE Then ' If only one record is displayed, verify that the copied fields ' are really intended to be pasted back into it If CountRecs% = 1 Then Begin Dialog PasteHere 227, 65, "Source record displayed" Text 14, 10, 196, 10, "This is the only available record! Paste copied " & Fields$ & " back into it?" ButtonGroup .choice PushButton 44, 30, 58, 18, "&Yes" PushButton 125, 30, 58, 18, "&No, exit macro" End Dialog Dim SourceRecord as PasteHere Dialog SourceRecord Select Case SourceRecord.choice Case 0 GoTo Paste: Case Else GoTo Done: End Select End If Clipboard.Clear CS.CopyControlNumber OCLCNumberTo$ = Clipboard.GetText() If OCLCNumberTo$ = OCLCNumberFrom$ Then SameRec = TRUE Else SameRec = FALSE End If If OCLCNumberTo$ = "NEW" Then OCLCNumberTo$ = Chr$( 034 ) & "NEW" & Chr$( 034 ) Else OCLCNumberTo$ = "#" & OCLCNumberTo$ End If ' Remove the words "Pinned" or "Workform" from the window title f = InStr( WindowTitle$, "(Pinned)" ) If f > 0 Then WindowTitle$ = Trim$( Mid$( WindowTitle$, 9 ) ) g = InStr( WindowTitle$, "Workform:" ) If g > 0 Then WindowTitle$ = Trim$( Mid$( WindowTitle$, 1, g + 7 ) ) Else Select Case TypeOfWindow% Case 0 'Online bibliographic record (WorldCat) WindowTitle$ = Trim$( Mid$( WindowTitle$, 17 ) ) Case 1 'Online bibliographic save file record WindowTitle$ = Trim$( Mid$( WindowTitle$, 33 ) ) Case 2 'Online bibliographic constant data record WindowTitle$ = Trim$( Mid$( WindowTitle$, 37 ) ) Case 3 'Online authority record (LC authority file) WindowTitle$ = Trim$( Mid$( WindowTitle$, 27 ) ) Case 4 'Online authority save file record WindowTitle$ = Trim$( Mid$( WindowTitle$, 29 ) ) Case 14 'Online authority constant data record WindowTitle$ = Trim$( Mid$( WindowTitle$, 33 ) ) Case 17 'Local bibliographic save file record WindowTitle$ = Trim$( Mid$( WindowTitle$, 51 ) ) Case 18 'Local authority save file record WindowTitle$ = Trim$( Mid$( WindowTitle$, 50 ) ) Case 19 'Local bibliographic constant data record WindowTitle$ = Trim$( Mid$( WindowTitle$, 60 ) ) Case 20 'Local authority constant data record WindowTitle$ = Trim$( Mid$( WindowTitle$, 58 ) ) End Select End If Else MsgBox "Sorry, an inexplicable error occurred.", 48, "Macro failed" GoTo Done: End If ' Shorten the title somewhat if it's too long If Len( WindowTitle$ ) > 80 Then WindowTitle$ = Left$( WindowTitle$, 80 ) & "..." If SameRec = TRUE Then WindowTitle$ = "Paste copied " & Fields$ & " back into the same record?" Else WindowTitle$ = "Paste copied " & Fields$ & " in this record (" & OCLCNumberTo$ & ", " & WindowTitle$ & ")?" End If Begin Dialog ChooseRecord 236, 88, "Select record for pasting fields" Text 28, 14, 182, 24, WindowTitle$ ButtonGroup .choice PushButton 22, 52, 58, 18, "&Yes" PushButton 88, 52, 58, 18, "&No, next record" PushButton 154, 52, 58, 18, "&Cancel" End Dialog Dim RecordChoice as ChooseRecord Dialog RecordChoice Select Case RecordChoice.choice Case 0 Paste: For e = 0 to EndOfFieldCount% If CS.AddField( 9, FieldsCopied$( e ) ) = FALSE Then MsgBox "Sorry, could not add a field.", 16, "Macro failed" GoTo Done: End If BeginningRow% = BeginningRow% + 1 Next e GoTo Done: Case 1 If c = CountRecs% - 1 Then If RecordKind$ = "B" Then MsgBox "No more bibliographic records! Exiting macro.", 64, "Macro finished" ElseIf RecordKind$ = "A" Then MsgBox "No more authority records! Exiting macro.", 64, "Macro finished" End If GoTo Done: Else GoTo Increment: End If Case 2 GoTo Done: End Select Increment: Next c Done: End Sub