![]() |
#1
|
|||
|
|||
![]()
Hey guys, this is my first post here! I'm a high school physics teacher in my 2nd year and i'm getting tired of the amount of copying that is happening in my Honors Physics class. I'd like to make a VBA macro that will randomize numbers on every copy i print for tests/worksheets. I use word 2016 at home and work.
Something where i could type a problem like this "Billy dropped a rock off a X meter high cliff. The rock has a mass of Y kilograms" And then when i print it i could print up 130 copies and word would automatically insert a random number within a designated range on each copy for the X and Y above. Below is what i have so far in code but i don't think it'll do the trick. Any advice? Thanks!!! Option Explicit Public Function RandomNumber(Lowest As Long, Highest As Long, _ Optional Decimals As Integer) If IsMissing(Decimals) Or Decimals = 0 Then Randomize RandomNumber = Int((Highest + 1 - Lowest) * Rnd + Lowest) Else Randomize RandomNumber = Round((Highest - Lowest) * Rnd + Lowest, Decimals) End If End Function Sub RNG1to10() Dim rn1 As Double Dim text As Double rn1 = RandomNumber(1, 10, 0) Selection.TypeText text:=rn1 End Sub |
#2
|
||||
|
||||
![]()
This looks fun, but it will take some thought how to record who has which version, but something along the lines of the following may help get you started.
Code:
Option Explicit Private Const sName As String = "Billy|Bobby|John|Susan|Ted" Private Const sPlace As String = "Cliff|Tower|Bridge" Private Const sItem As String = "Stone|Rock|Wrench" Private vName As Variant, vPlace As Variant, vItem As Variant Private iPlace As Integer, iName As Integer, iItem As Integer Private iHeight As Integer, iMass As Integer Private sText As String Private Function RandomNumber(Lowest As Long, Highest As Long, _ Optional Decimals As Integer) As Integer If IsMissing(Decimals) Or Decimals = 0 Then Randomize RandomNumber = Int((Highest + 1 - Lowest) * Rnd + Lowest) Else Randomize RandomNumber = Round((Highest - Lowest) * Rnd + Lowest, Decimals) End If End Function Sub Macro1() vName = Split(sName, "|") vPlace = Split(sPlace, "|") vItem = Split(sItem, "|") iHeight = RandomNumber(1, 50, 0) iMass = RandomNumber(1, 5, 0) iPlace = RandomNumber(0, UBound(vPlace)) iName = RandomNumber(0, UBound(vName)) iItem = RandomNumber(0, UBound(vItem)) sText = vName(iName) & " dropped a " & vItem(iItem) & " off a " & iHeight & " meter-high " & _ vPlace(iPlace) & ". The " & vItem(iItem) & " has a mass of " & iMass & " kilograms." Selection.TypeText sText End Sub
__________________
Graham Mayor - MS MVP (Word) (2002-2019) Visit my web site for more programming tips and ready made processes www.gmayor.com |
#3
|
|||
|
|||
![]() Quote:
I'll update again once i make progress. Thanks again for giving me such a solid foundation!!! ![]() |
#4
|
||||
|
||||
![]()
Another possibility is to put the variations in a worksheet (where you can also calculate the answers in a second complementary worksheet) and associate each variation with a student and use mail merge to create a custom version of the question paper for each student. That would also make it easier to add mutiple questions. You can then compare the student's answers with the question sheet and more easily identify where the plagiarism comes from.
You could mix a few fixed questions with the random questions (especially the first questions so the plagiarists may not immediately notice)
__________________
Graham Mayor - MS MVP (Word) (2002-2019) Visit my web site for more programming tips and ready made processes www.gmayor.com |
#5
|
|||
|
|||
![]()
Do you mean that instead of including each question in the code, just have the questions written out in a word doc and then do a search and replace to add in random numbers? That does sound easier as i wouldn't have to format each question in code format and could type them out in an easier manner.
|
#6
|
||||
|
||||
![]()
Not quite. I'll throw together an example tomorrow. I've had enough for today.
__________________
Graham Mayor - MS MVP (Word) (2002-2019) Visit my web site for more programming tips and ready made processes www.gmayor.com |
#7
|
|||
|
|||
![]()
Ok Cool dude. Thanks again for your help, hope you have a good evening! I've worked on it some today and this is what it looks like right now. Its working and outputting the answers properly. Good progress!!!
![]() Code: Option Explicit Private Const sName As String = "Billy|Melanie|John|Susan|Ted|Christine|Bobby" Private Const sPlace As String = "Cliff|Tower|Bridge|Skyscraper" Private Const sItem As String = "Stone|Rock|Wrench|Box|Crate|Suitcase" Private vName As Variant, vPlace As Variant, vItem As Variant Private iPlace As Integer, iName As Integer, iItem As Integer Private iHeight As Double, iMass As Double Private sText As String Private Function RandomNumber(Lowest As Long, Highest As Long, _ Optional Decimals As Integer) As Integer If IsMissing(Decimals) Or Decimals = 0 Then Randomize RandomNumber = Int((Highest + 1 - Lowest) * Rnd + Lowest) Else Randomize RandomNumber = Round((Highest - Lowest) * Rnd + Lowest, Decimals) End If End Function Function FileExists(FName As String) As Boolean ' Returns True if the file FName exists, else False Dim fs Set fs = CreateObject("Scripting.FileSystemObject") FileExists = fs.FileExists(FName) Set fs = Nothing End Function Sub anticopy() Dim oxlApp As Object ' Used for the Excel App Dim oxlWbk As Object ' Used for the Workbook Dim FN As String Dim AnswerA As Single ' Part A solution Dim AnswerB As Single ' Part B solution Dim AnswerC As Single ' Part C solution FN = "C:\users\proctor.david\documents\vba\testanswers. xlsx" ' Spreadsheet Name vName = Split(sName, "|") vPlace = Split(sPlace, "|") vItem = Split(sItem, "|") iHeight = RandomNumber(20, 80, 1) iMass = RandomNumber(2, 25, 0) iPlace = RandomNumber(0, UBound(vPlace)) iName = RandomNumber(0, UBound(vName)) iItem = RandomNumber(0, UBound(vItem)) AnswerA = iMass * 9.8 AnswerB = ((2 * iHeight) / 9.8) ^ 0.5 AnswerC = 9.8 * AnswerB sText = vName(iName) & " dropped a " & vItem(iItem) & " off a " & iHeight & " meter-high " & _ vPlace(iPlace) & ". The " & vItem(iItem) & " has a mass of " & iMass & " kilograms." & _ Chr(11) & Chr(9) & "A. Calculate the force of gravity on the " & vItem(iItem) & "." & Chr(11) & _ Chr(9) & "B. Calculate the time it will take to hit the ground. Ignore air resistance." & _ Chr(11) & Chr(9) & "C. How fast will the " & vItem(iItem) & " be falling when it hits the ground?" & _ Chr(11) Selection.TypeText sText Set oxlApp = CreateObject("Excel.Application") If FileExists(FN) Then ' Check to see if the spreadsheet exists. Set oxlWbk = oxlApp.Workbooks.Open(FileName:=FN) ' Open the Workbook oxlWbk.ActiveSheet.Cells(1, 1).Value = AnswerA oxlWbk.ActiveSheet.Cells(1, 2).Value = AnswerB oxlWbk.ActiveSheet.Cells(1, 3).Value = AnswerC oxlWbk.Close SaveChanges:=True ' Close the spreadsheet, saving the changes. Set oxlWbk = Nothing Else ' It does not exist so tell the user. MsgBox "Excel File " & FN & " not found" End If ' Close the Excel App cleanly oxlApp.Quit Set oxlApp = Nothing End Sub |
#8
|
||||
|
||||
![]()
I think you are on top of this, though if I may suggest a couple of modifications, the following will create the workbook and record all the required answers. The code creates 10 pages, but you can make that any number you like.
Code:
Option Explicit Private Const sName As String = "Billy|Melanie|John|Susan|Ted|Christine|Bobby" Private Const sPlace As String = "cliff|tower|bridge|building" Private Const sItem As String = "stone|rock|wrench|box|crate|suitcase" Private Const iPages As Integer = 10 'the number of pages to create Private vName As Variant, vPlace As Variant, vItem As Variant Private iPlace As Integer, iName As Integer, iItem As Integer Private iHeight As Double, iMass As Double Private i As Integer Private oxlApp As Object ' Used for the Excel App Private oxlWbk As Object ' Used for the Workbook Private FN As String Private oDoc As Document Private oRng As Range Private sText As String Private NextRow As Long Private AnswerA As Single ' Part A solution Private AnswerB As Single ' Part B solution Private AnswerC As Single ' Part C solution Sub anticopy() Set oDoc = Documents.Add Set oRng = oDoc.Range FN = Environ("USERPROFILE") & "\documents\vba" ' Spreadsheet Folder CreateFolders FN FN = FN & "testanswers.xlsx" Set oxlApp = CreateObject("Excel.Application") If FileExists(FN) Then ' Check to see if the spreadsheet exists. Set oxlWbk = oxlApp.Workbooks.Open(FileName:=FN) ' Open the Workbook Else ' It does not exist so tell the user. Set oxlWbk = oxlApp.Workbooks.Add With oxlWbk .Sheets(1).Cells(1, 1).Value = "Student" .Sheets(1).Cells(1, 2).Value = "AnswerA" .Sheets(1).Cells(1, 3).Value = "AnswerB" .Sheets(1).Cells(1, 4).Value = "AnswerC" .SaveAs FN End With End If vName = Split(sName, "|") vPlace = Split(sPlace, "|") vItem = Split(sItem, "|") For i = 1 To iPages 'create the question documents iHeight = RandomNumber(20, 80, 1) iMass = RandomNumber(2, 25, 0) iPlace = RandomNumber(0, UBound(vPlace)) iName = RandomNumber(0, UBound(vName)) iItem = RandomNumber(0, UBound(vItem)) AnswerA = iMass * 9.8 AnswerB = ((2 * iHeight) / 9.8) ^ 0.5 AnswerC = 9.8 * AnswerB sText = "Student " & i & vbCr & vName(iName) & " dropped a " & vItem(iItem) & " off a " & iHeight & " meter-high " & _ vPlace(iPlace) & ". The " & vItem(iItem) & " has a mass of " & iMass & " kilograms." & _ Chr(11) & Chr(9) & "A. Calculate the force of gravity on the " & vItem(iItem) & "." & Chr(11) & _ Chr(9) & "B. Calculate the time it will take to hit the ground. Ignore air resistance." & _ Chr(11) & Chr(9) & "C. How fast will the " & vItem(iItem) & " be falling when it hits the ground?" & _ Chr(11) oRng.Text = sText oRng.Collapse 0 If i < iPages Then oRng.InsertBreak Type:=0 oRng.Collapse 0 End If NextRow = oxlWbk.Sheets(1).Range("A" & oxlWbk.Sheets(1).Rows.Count).End(-4162).Row + 1 With oxlWbk .Sheets(1).Cells(NextRow, 1).Value = "Student " & i .Sheets(1).Cells(NextRow, 2).Value = AnswerA .Sheets(1).Cells(NextRow, 3).Value = AnswerB .Sheets(1).Cells(NextRow, 4).Value = AnswerC End With Next i oxlWbk.Close SaveChanges:=True ' Close the spreadsheet, saving the changes. Set oxlWbk = Nothing ' Close the Excel App cleanly oxlApp.Quit Set oxlApp = Nothing End Sub Private Function RandomNumber(Lowest As Long, Highest As Long, _ Optional Decimals As Integer) As Integer If IsMissing(Decimals) Or Decimals = 0 Then Randomize RandomNumber = Int((Highest + 1 - Lowest) * Rnd + Lowest) Else Randomize RandomNumber = Round((Highest - Lowest) * Rnd + Lowest, Decimals) End If End Function Private Function FileExists(FName As String) As Boolean ' Returns True if the file FName exists, else False Dim fs Set fs = CreateObject("Scripting.FileSystemObject") FileExists = fs.FileExists(FName) Set fs = Nothing End Function Private Sub CreateFolders(strPath As String) 'A Graham Mayor/Greg Maxey AddIn Utility Macro Dim oFSO As Object Dim lngPathSep As Long Dim lngPS As Long If Right(strPath, 1) <> "\" Then strPath = strPath & "\" lngPathSep = InStr(3, strPath, "\") If lngPathSep = 0 Then GoTo lbl_Exit Set oFSO = CreateObject("Scripting.FileSystemObject") Do lngPS = lngPathSep lngPathSep = InStr(lngPS + 1, strPath, "\") If lngPathSep = 0 Then Exit Do If Len(Dir(Left(strPath, lngPathSep), vbDirectory)) = 0 Then Exit Do Loop Do Until lngPathSep = 0 If Not oFSO.FolderExists(Left(strPath, lngPathSep)) Then oFSO.CreateFolder Left(strPath, lngPathSep) End If lngPS = lngPathSep lngPathSep = InStr(lngPS + 1, strPath, "\") Loop lbl_Exit: Set oFSO = Nothing Exit Sub End Sub
__________________
Graham Mayor - MS MVP (Word) (2002-2019) Visit my web site for more programming tips and ready made processes www.gmayor.com |
#9
|
|||
|
|||
![]()
I love you.
|
#10
|
||||
|
||||
![]()
Steady.
![]()
__________________
Graham Mayor - MS MVP (Word) (2002-2019) Visit my web site for more programming tips and ready made processes www.gmayor.com |
![]() |
Tags |
word 2016 |
|