I am making an Excel sheet for keeping track of courses and its participants.

The format is as such:

01. Place  | Time | Date | Slots
02. SO.com   Now     Now     5
03. SE.com   Soon    Soon    10

And etc.

This list is sent to me with anywhere from 10 to 50 courses at a time, and I want to keep track of the participants for each course in the same file.

So ideally, I want to run a macro that, under the course for SO.com, creates 5 (See Slots) new rows, and then replaces the value 5 with a =COUNTBLANK for the range that was just created, so that the "Slots" value will now show how many free slots there are instead of the total number of slots. Bonus points if anyone can point me to how I can make the macro group the created selection as well.

The macro should loop through the entire worksheet and do the same operation for every course.

The result should look like this:

01. Place | Time | Date | Slots
02. SO.com  Now     Now     5
03. <empty>
04. <empty>
05. <empty>
06. <empty>
07. <empty>
08. SE.com  Soon    Soon    10
09. <empty>
10. <empty>
...

Entering the participants into the Excel field is done through copypasta, as I have a system for mass exporting this information from a different program.

I'm very new at VBA, but below is my initial attempt at starting to construct this code. I cut some code from other parts of the web, did some lookups to MSDN, and guesstimated the rest, and not very surprisingly, it doesn't quite work yet. I get an object required error on the line starting with "Set cellCount = Worksheets [...]" and I don't understand why.

Any input on other parts of the process (if you see that my code is stillborn regardless of the object error, for example) is also appreciated.


Sub insertRowsCourseSpace()

    Dim i&
    Dim cellCount As Integer
    Dim a As Integer

    'Locate the column to look for course space values    
    Dim col_n As Long
        For f = 1 To NumCols
        If Cells(2, f).Value = "Slots" Then col_n = f 'Finding the cell with the given string sets the column number
    Next

    'If cell value is numerical, create rows equal to value
    For i = 1 To NumRows
        If IsNumeric(Worksheets(1).Range(col_n & i).Value) = True Then
            Set cellCount = Worksheets(1).Range(col_n & i).Value
            Set Worksheets(1).Range(col_n & i).Value = "=COUNTBLANK(ActiveCell.Offset(1):ActiveCell(Offset(1 + cellCount))"
            For j = 1 To cellCount
                ActiveCell.Offset(j).EntireRow.Insert
            Next j
    Next i

End Sub

EDIT:

OK, new attempt:

Using this workbook: http://s000.tinyupload.com/?file_id=02770147469124312893

Sub insertRowsCourseSlots()

Dim i&
Dim cellCount As Integer
Dim cellValue As Integer
Dim a As String
Dim b As String

'Locate correct column to look for course slots
'Dim col_n As Long
'
'    For f = 1 To 15 'Course slots won't be located further out than 15 columns, arbitrary value
'    If Cells(2, f).Value = "Antall kursplass" Then col_n = f
'Next

'If cell value is numerical, insert number of rows equal to the cell value
For i = 3 To 400 '400 = Arbitrary number
    If IsNumeric(Sheets("Sheet1").Cells(2, i).Value) = True Then
        cellValue = Sheets("Sheet1").Cells(2, i).Value
        cellCount = cellValue
        a = ActiveCell.Offset(1)
        b = ActiveCell.Offset(1) + CStr(cellCount)
        Set Sheets("Sheet1").Cells(2, i).Value = "=COUNTBLANK(a:b)"
        For j = 1 To cellCount
            ActiveCell.Offset(j).EntireRow.Insert
        Next j
    End If
Next i 
End Sub

This gives me Runtime error '9', subscript out of range, on the line Set Sheets("Sheet1").Cells(2, i).Value = "=COUNTBLANK(a:b)"

share
    
If I understand correctly, you receive a list with courses including the amount of slots per course. Then you want to insert that amount of slots as blank rows below each course line? – Jens Feb 25 '15 at 10:06
    
Will the layout of the table always be like in the top example? If so there is really no point in searching for the correct column-header, as it'll always be in the same column. – eirikdaude Feb 25 '15 at 10:11
    
@Jens that is correct. – Vegard Feb 25 '15 at 11:21
    
I believe the cause of your error is the use of the 'Set' keyword, which sets a reference to an object. Since integer variables aren't objects you don't need this keyword. The rest of your code others seem to have made some attempt at in their answers. – Aiken Feb 25 '15 at 12:25
up vote 1 down vote accepted

Here is my take on your problem. Please note that you'll probably run into trouble if the data isn't formatted as it seems to be in your top post, or if there e.g. are empty cells in the column describing number of participants.

As to your own code, I didn't look too closely into it, as I found it easier to start from scratch, but from what I saw I'd strongly recommend you to use Option Explicit at the top of your modules, forcing you to declare all your variables. Where are you for instance getting the values for NumCols or NumRows from?

As to why the sub aborts at the line it does, I believe it is because the argument you pass to Worksheets.Range() is not valid.

Sub insertRowsCourseSpace()
  Dim no_to_insert() As Variant, v As Variant, at_row_number As Long, i As Long

  no_to_insert = Range(Worksheets("Sheet1").Range("E2"), Worksheets("Sheet1").Range("E1048576").End(xlUp))
  at_row_number = 2

  For Each v In no_to_insert
    ' Inserts new rows
    Worksheets("Sheet1").Rows(CStr(at_row_number + 1) & ":" & CStr(at_row_number + CLng(v))).Insert shift:=xlDown
    ' Inserts formula
    Worksheets("Sheet1").Range("E" & CStr(at_row_number)).Formula = "=COUNTBLANK(B" & CStr(at_row_number + 1) & ":B" & CStr(at_row_number + CLng(v)) & ")"
    ' Name range
    Worksheets("Sheet1").Range("A2:E2").Offset(at_row_number - 2, 0).Resize(CLng(v) + 1, 5).Name = "Range" & CStr(i)
    i = i + 1
    ' Decides where to insert the new set of rows
    at_row_number = at_row_number + CLng(v) + 1
  Next
  With Worksheets("Sheet1").Range("A1")
    .Value = "01."
    .AutoFill .Resize(at_row_number, 1), xlFillSeries
  End With
End Sub

Updated code:

Sub insertRowsCourseSpace()
  Dim no_to_insert() As Variant, v As Variant, at_row_number As Long, i As Long

  no_to_insert = Range(Worksheets("Sheet1").Range("B3"), Worksheets("Sheet1").Range("B1048576").End(xlUp))
  at_row_number = 3

  For Each v In no_to_insert
    ' Inserts new rows
    Worksheets("Sheet1").Rows(CStr(at_row_number + 1) & ":" & CStr(at_row_number + CLng(v))).Insert shift:=xlDown
    ' Inserts formula
    Worksheets("Sheet1").Range("B" & CStr(at_row_number)).Formula = "=COUNTBLANK(A" & CStr(at_row_number + 1) & ":A" & CStr(at_row_number + CLng(v)) & ")"
    ' Name range
    Worksheets("Sheet1").Range("A3:H3").Offset(at_row_number - 3, 0).Resize(CLng(v) + 1, 8).Name = "Range" & CStr(i)
    i = i + 1
    ' Decides where to insert the new set of rows
    at_row_number = at_row_number + CLng(v) + 1
  Next
  'With Worksheets("Sheet1").Range("A1")
  '  .Value = "01."
  '  .AutoFill .Resize(at_row_number, 1), xlFillSeries
  'End With
End Sub
share
    
I can't get your code to work. Debugger says type mismatch on row 11: – Vegard Feb 25 '15 at 11:53
    
It works for me. Is there something else than the number of open slots in your column E? – eirikdaude Feb 25 '15 at 12:04
    
There is a column header, similar to how it appears in the example. – Vegard Feb 25 '15 at 12:08
    
Yeah, that's why it starts in E2/row 2. What is the line it stops on? For me line 11 is Worksheets("Sheet1").Range("E" & CStr(at_row_number)).Formula = "=COUNTBLANK(B" & CStr(at_row_number + 1) & ":B" & CStr(at_row_number + CLng(v)) & ")" Are you able to post an actual sample workbook somewhere? – eirikdaude Feb 25 '15 at 12:12
    
s000.tinyupload.com/?file_id=02770147469124312893 The formatting isn't the same as in my original post (but the testbook I tried your code was!), this is the production sample layout with bogus data. Sheet 2 contains an estimate of the result (I only formatted the top 3 courses) - the lines that are filled in with Does are just examples of what I would do with the file after the macro has run, and how the COUNTBLANK function needs to play into it all. – Vegard Feb 25 '15 at 12:46

May I suggest transferring your data to ms access? Even though what you are asking is easily possible in excel, I don't think it will let you keep track of everything in a handy way.

My suggestion is, create two tables in ms access. One with all your courses, and with all participants, regardless of the course. The you add a reference in the participants table, in which you connect the correct course ID from the first table. Afterwards, you can easily run a query to get all your data. If you want to, you can always export your data to excel.

Should you really want to do it in excel for whatever reason, leave a comment and I'll help you out.

share
    
MS Access is unfortunately not an option - believe me, my first thought about this problem was to export it to a database. The powers that be have decided that I must use Excel. – Vegard Feb 25 '15 at 11:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.