Results 21 to 40 of 56

Thread: How to scramble tables in word

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #16
    Microsoft Word MVP 2003-2009 VBAX Guru gmaxey's Avatar
    Joined
    Sep 2005
    Posts
    3,411
    Location
    Gents,

    Yes. Like a dog with a bone, I can't let it go

    mana, I ran your code with my 250 question bank split in 12 sections (20 in sections 1-11 and 10 in section 12). Using your logic, I got the not enough questions alert when I asked for a test of 150 questions. I can see that there is practically unlimited number of possibilities for section count and questions per section so I just tried to write something that would work for that case. What I've done is attempt to resolve a mix of questions from each section until the total requested is met. I'm not that proficient with a dictionary so I used an array.

    Kilroy, as defined, wouldn't your test bank have 482 question if section 1 only has 2 questions ?
    Can you test with your bank and see what results you get:

    Sub CreateTestAdv2()
    Dim oDocBank As Document
    Dim oBankTbls As Tables
    Dim oDic As Object, oRanNumGen As Object
    Dim lngIndex As Long, lngQuestions As Long
    Dim lngSecCount As Long
    Dim lngLow As Long, lngHigh As Long
    Dim lngPerBank As Long, lngRandom As Long, lngCheck As Long
    Dim lngCumulative As Long
    Dim arrPerSection()
    Dim oRng As Range, oRngInsert As Range
    Dim oFld As Field
    
      ClearQuestions
      'Open the test bank document.
      Set oDocBank = Documents.Open(ThisDocument.Path & "\Test Bank 250.docm", , , False, , , , , , , , False)
      'Iniitalize a dictionary and random number generator object.
      Set oDic = CreateObject("scripting.dictionary")
      Set oRanNumGen = CreateObject("system.random")
      'Get the number of questions.
      lngQuestions = CLng(InputBox("Enter the number of test questions", "NUMBER OF QUESTIONS", "100"))
      If lngQuestions > oDocBank.Tables.Count Then
        MsgBox "There is not enough questions in the test bank to generate the defined test.", vbInformation + vbOKOnly, "TEST SIZE TOO LARGE FOR BANK"
        GoTo lbl_Exit
      End If
      lngSecCount = oDocBank.Sections.Count
      'Develop and store the number of questions to take from each section.
      If lngQuestions / oDocBank.Sections.Count - Int(lngQuestions / oDocBank.Sections.Count) >= 0.5 Then
        lngPerBank = (lngQuestions \ oDocBank.Sections.Count) + 1
      Else
        lngPerBank = lngQuestions \ oDocBank.Sections.Count
      End If
      ReDim arrPerSection(1 To lngSecCount)
      For lngIndex = 1 To lngSecCount
        If oDocBank.Sections(lngIndex).Range.Tables.Count > lngPerBank Then
          arrPerSection(lngIndex) = lngPerBank
        Else
          arrPerSection(lngIndex) = oDocBank.Sections(lngIndex).Range.Tables.Count
        End If
      Next
      Do
        'Check and resolve questions per section until correct total is achieved.
        lngCheck = 0
        For lngIndex = 1 To UBound(arrPerSection)
          lngCheck = lngCheck + arrPerSection(lngIndex)
        Next
        Select Case True
          Case lngCheck > lngQuestions
            lngRandom = oRanNumGen.next_2(1, lngSecCount + 1)
            If arrPerSection(lngRandom) > 1 Then
              arrPerSection(lngRandom) = arrPerSection(lngRandom) - 1
            End If
          Case lngCheck < lngQuestions
            lngRandom = oRanNumGen.next_2(1, lngSecCount + 1)
            If oDocBank.Sections(lngRandom).Range.Tables.Count > arrPerSection(lngRandom) Then
              arrPerSection(lngRandom) = arrPerSection(lngRandom) + 1
            End If
          Case Else
            Exit Do
        End Select
      Loop
      'Get the random questions from each section.
      For lngIndex = 1 To UBound(arrPerSection)
        lngCumulative = lngCumulative + arrPerSection(lngIndex)
        Set oBankTbls = oDocBank.Sections(lngIndex).Range.Tables
        Set oRng = oDocBank.Range
        oRng.End = oBankTbls.Item(1).Range.Start
        lngLow = oRng.Tables.Count
        If lngLow > 1 Then lngLow = lngLow + 1
        Set oRng = oDocBank.Range
        oRng.End = oBankTbls.Item(oBankTbls.Count).Range.End
        lngHigh = oRng.Tables.Count
        Do
          lngRandom = oRanNumGen.next_2(lngLow, lngHigh + 1)
          oDic(lngRandom) = Empty
          If oDic.Count = lngCumulative Then Exit Do
          If oDic.Count = lngQuestions Then Exit Do
        Loop
      Next lngIndex
      Application.ScreenUpdating = False
      Set oBankTbls = oDocBank.Tables
      'Replicate the question bank random questions in the active document.
      For lngIndex = 1 To oDic.Count
       Set oRngInsert = ActiveDocument.Bookmarks("QuestionAnchor").Range
        Set oRng = oBankTbls(oDic.keys()(lngIndex - 1)).Range
        With oRngInsert
          .FormattedText = oRng.FormattedText
          .Collapse wdCollapseEnd
          .InsertBefore vbCr
          .Collapse wdCollapseEnd
        End With
        ActiveDocument.Bookmarks.Add "QuestionAnchor", oRngInsert
      Next
      Application.ScreenUpdating = True
      For Each oFld In ActiveDocument.Fields
        'Unlink the sequential question bank number field.
        If InStr(oFld.Code, "Bank") > 0 Then oFld.Unlink
      Next oFld
      'Update the sequential question number field.
      ActiveDocument.Fields.Update
    lbl_Exit:
      oDocBank.Close wdDoNotSaveChanges
      Set oDic = Nothing: Set oRanNumGen = Nothing
      Set oDocBank = Nothing: Set oBankTbls = Nothing
      Set oRng = Nothing: Set oRngInsert = Nothing: Set oFld = Nothing
      Exit Sub
    End Sub

    Hmm. Thoughts after posting:
    1. Maybe something to ensure that that question per section is never reduced to 0 would be the next thing ;-). Fixed in code above
    2. Maybe a dialog to pick the test bank.
    Last edited by gmaxey; 08-16-2019 at 10:35 AM. Reason: After thoughts and adjust code.
    Greg

    Visit my website: http://gregmaxey.com

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •