Respondus to Quizmaker macro

Mar 18, 2014

Hi, I created a Word VBA Macro to convert Respondus quizzes to a txt file that Quizmaker could import.

It started out as a proof of concept, and only had to run it once, so the code is sloppy.     (Had over 350 questions to import.)

Only works for T/F and Multiple choice now, but if you know a bit of VBA, could modify to include other question types.

Directions:

1)      In Respondus, export to Word your questions as a test with correct answers marked.

2)      Open the exported Word file, go to the Developer tab, Macros button (on left).  Click edit, and  Paste in the attached macro code.

3)      Run the macro, it will create a new file in whatever directory the file was saved in with the questions now formatted in Quizmaker format.

4)      Go to Quizmaker and import the file.

Code:  (also attached)

Sub Respondus_to_Quizmaker()
'
' Respondus_to_Quizmaker Macro
'
' Created by Tim Welch @ The Ohio State University
' Date: 12/12/13
'
' NOTES:
' Only converts True/False and Multiple Choice questions
' Respondus file character size limited by VBA String object max length (which is ~ 2 billion characters)
'

Dim sText As String 'The text from the Respondus file
Dim iStringLength As Long 'The length of the string
Dim iCurrentPosition As Long ' The current location in the string being examined
iCurrentPosition = 1 ' Initialize at the 1st position

' Read in the quiz questions to string sText
' (As VBA strings are immutable, we will remember our position when using this string instead of
' changing it and thus creating a new string.)
sText = ActiveDocument.Content

' Replace all occurences of line feed (aka line wrap), asii code 11 with a space, asii code 32
sText = Replace(sText, Chr(11), Chr(32))

' Delete all text in the Word file (as we do not save, this does not matter to the Respondus output file)
ActiveDocument.Content.Delete

' Print the heading information at the top of the document
Selection.TypeText ("// Created from: " & ActiveDocument.Name & Chr(13))
Selection.TypeText ("// On date: " & Format(Date, "dddd, d MMMM YYYY") & Chr(13) & Chr(13))

' Set iStringLength to the length of the string
iStringLength = Len(sText)

' Move thru the string converting each question to Respondus format and
' printing it to the cleared open Word document being used as a Temp location for the changes
Do While iCurrentPosition <> iStringLength
    Call ConvertToRespondusFormat(iCurrentPosition, iStringLength, sText)
Loop

' Save modified file as text file to allow easy importing to Respondus
Call SaveAsTextFile

' Close the open Word file without saving
Application.Quit SaveChanges:=wdDoNotSaveChanges

End Sub

Private Sub SaveAsTextFile()
' Saves Current Word file to a text file with the same name in the same directory it is saved to.
'
' Modified from code found at:
' http://msdn.microsoft.com/en-us/library/office/aa662158(v=office.10).aspx
'
Dim strDocName As String
Dim intPos As Long

'Find position of extension in file name
strDocName = ActiveDocument.Name
intPos = InStrRev(strDocName, ".")

If intPos = 0 Then

'If the document has not yet been saved
'Ask the user to provide a file name
strDocName = InputBox("Please enter the name " & _
"of your document.")
Else

'Strip off extension and add ".txt" extension
strDocName = Left(strDocName, intPos - 1)
strDocName = strDocName & ".txt"
End If

'Save file with new extension
' ActiveDocument.Path & changes the default save path (My Documents)
' to the current directory
' "\\WordBackupFolder\Error folder" & "\"
ActiveDocument.SaveAs fileName:=ActiveDocument.Path & "\" & strDocName, _
FileFormat:=wdFormatText

End Sub

Private Sub ConvertToRespondusFormat(iCurrentPosition As Long, iStringLength As Long, sText As String)
'
'
'
Dim sQuestionLine As String

' Get just the question text
' Respondus format for questions always starts a question with a # followed by a period as the first items on a line
' So it looks like: ####. This is the question.
' QuizMaker does not have question numbers so it needs to be removed
sQuestionLine = QuestionLine(sText, iCurrentPosition)

' Check if the current question is True False or Multiple Choice and handle appropriately
If IsTrueFalse(sText, iCurrentPosition) Then
    Call QuestionTrueFalse(sQuestionLine, iCurrentPosition, iStringLength, sText)
Else
    Call QuestionMultipleChoice(sQuestionLine, iCurrentPosition, iStringLength, sText)
End If

End Sub

Function IsTrueFalse(sText, iCurrentPosition) As Boolean
' Returns True if the question is a True False question
       
    ' Look for "a. True" on first question line (which is where the iCurrentPosition is at)
    Dim iIsTrue As Long
    Dim sCurrentLine As String
    Dim iEndofLine As Long
       
    ' Find the end of the line
    iEndofLine = InStr(iCurrentPosition, sText, Chr(13))
   
    'Get the current line which will be the first answer line
    sCurrentLine = Mid(sText, iCurrentPosition, (iEndofLine - iCurrentPosition))
   
    iIsTrue = InStr(sCurrentLine, "a. True")
   
    ' Check if T/F, if so, return true
    If iIsTrue Then
        IsTrueFalse = True
    Else
        IsTrueFalse = False
    End If
   
End Function

Function QuestionLine(sText, iCurrentPosition) As String
' Returns a String containing the current question line without the leading "####. "
' Updates the location of iCurrentPosition to the start of the 1st answer line
   
    Dim sCurrentLine As String
    Dim iEndofLine As Long
   
    ' Need to move to the start of the question (aka Need to move past "####. ")
    iCurrentPosition = InStr(iCurrentPosition, sText, ". ") + 2
       
    ' Find the end of the line
    iEndofLine = InStr(iCurrentPosition, sText, Chr(13))
   
    'Get the current line which will be the question line
    sCurrentLine = Mid(sText, iCurrentPosition, (iEndofLine - iCurrentPosition))
   
    ' Update iCurrentPosition to the first answer choice
    iCurrentPosition = iEndofLine + 2
   
    QuestionLine = sCurrentLine
   
End Function

Function AnswerLine(sText, iCurrentPosition) As String
' Returns a String containing the current answer line without the leading "(letter). "
' Updates the location of iCurrentPosition to the start of the next line
   
    Dim sCurrentLine As String
    Dim iEndofLine As Long
   
    ' Need to move to the start of the answer (aka Need to move past "(letter). ")
    iCurrentPosition = InStr(iCurrentPosition, sText, ". ") + 2
       
    ' Find the end of the line
    iEndofLine = InStr(iCurrentPosition, sText, Chr(13))
   
    'Get the current line which will be the answer line
    sCurrentLine = Mid(sText, iCurrentPosition, (iEndofLine - iCurrentPosition))
   
    ' Update iCurrentPosition to the next line
    iCurrentPosition = iEndofLine + 1
   
    AnswerLine = sCurrentLine
   
End Function

Private Sub QuestionTrueFalse(sQuestionLine As String, iCurrentPosition As Long, iStringLength As Long, sText As String)
'
'
'
    Dim sAnswerLine As String
    Dim bAnswerCorrect As Boolean
   
    ' Write that the question if True/False
    Selection.TypeText ("TF" & Chr(13))
   
    ' Assign Point value of question
    Selection.TypeText ("1" & Chr(13))
   
    ' Write the question line
    Selection.TypeText (sQuestionLine & Chr(13))
       
    ' Cycle thru the answers and print them out
    Do While Mid(sText, iCurrentPosition, 1) <> Chr(13)
        ' Check if the answer is correct, write the "*" if it is
        If Mid(sText, iCurrentPosition, 1) = "*" Then
            Selection.TypeText ("*")
            bAnswerCorrect = True
            iCurrentPosition = iCurrentPosition + 1
        Else
            bAnswerCorrect = False
        End If
       
        ' Get the Answer line and update iCurrentPosition
        sAnswerLine = AnswerLine(sText, iCurrentPosition)
       
        ' Write the answer
        Selection.TypeText (sAnswerLine & Chr(13))
    Loop
       
    ' Check to see if within 5 spaces of the end, if so, set to stop
    ' If not, advance to the next Question and put a space between questions
    If (iCurrentPosition + 5) >= iStringLength Then
        iCurrentPosition = iStringLength
    Else
        iCurrentPosition = iCurrentPosition + 2
        Selection.TypeText (Chr(13))
    End If

End Sub

Private Sub QuestionMultipleChoice(sQuestionLine As String, iCurrentPosition As Long, iStringLength As Long, sText As String)
'
'
'
    Dim sAnswerLine As String
    Dim bAnswerCorrect As Boolean
   
    ' Write that the question is Multiple Choice
    Selection.TypeText ("MC" & Chr(13))
   
    ' Assign Point value of question
    Selection.TypeText ("1" & Chr(13))
   
    ' Write the question line
    Selection.TypeText (sQuestionLine & Chr(13))
       
    ' Cycle thru the answers and print them out
    Do While Mid(sText, iCurrentPosition, 1) <> Chr(13)
        ' Check if the answer is correct, write the "*" if it is
        If Mid(sText, iCurrentPosition, 1) = "*" Then
            Selection.TypeText ("*")
            bAnswerCorrect = True
            iCurrentPosition = iCurrentPosition + 1
        Else
            bAnswerCorrect = False
        End If
       
        ' Get the Answer line and update iCurrentPosition
        sAnswerLine = AnswerLine(sText, iCurrentPosition)
       
        ' Write the answer
        Selection.TypeText (sAnswerLine & " | ")
       
        ' Write the correct comment
        If bAnswerCorrect Then
            Selection.TypeText ("That's correct!" & Chr(13))
        Else
            Selection.TypeText ("That's incorrect." & Chr(13))
        End If
    Loop
       
    ' Check to see if within 5 spaces of the end, if so, set to stop
    ' If not, advance to the next Question and put a space between questions
    If (iCurrentPosition + 5) >= iStringLength Then
        iCurrentPosition = iStringLength
    Else
        iCurrentPosition = iCurrentPosition + 2
        Selection.TypeText (Chr(13))
    End If

End Sub

Be the first to reply

This discussion is closed. You can start a new discussion or contact Articulate Support.