views:

43

answers:

2

Hey guys, So I am working on a reporting tool in Access. It queries the local tables and creates a Excel document (through VBA) and makes an Excel file.

I use the following code to color alternative code and it works beautifully

 For a = 1 To rs.RecordCount
    With ExcelSheet          
        .Cells(a + 1, 1) = a 
        .Cells(a + 1, 1).EntireRow.Interior.ColorIndex = IIf((a + 1) Mod 2 = 0, 2, 15)
    End With
Next

Note I have to do a + 1 because a = 1 is the title row, and that is the title row.

Note: .Cells(a + 1, 1) = 1 numbers the rows (1 , 2, 3, ...)

Note : IIf((a + 1) Mod 2 = 0, 2, 15) The 2 and 15 are color codes.

Now my question is that when someone gets the Excel report they might delete a row, or do a sort operation or whatever and when they do that, it messes up the rows.

ex:

1  white row
2  grey row
3  white row 
4  grey row

if i sort them I get

3  white row
1  white row 
2  grey row 
4  grey row 

which is not what I want, I want it to keep the formatting and the numbering Anyone to accomplish this using VBA in Access?

Tech: Office 2007

+3  A: 

This can be accomplished with the ROW() function and some conditional formatting. The ROW() function returns the current row of the cell it is in, so it will change whenever cells are deleted, moved or sorted. Conditional formatting is re-applied whenever its conditions change, so moving or sorting rows would inform Excel to update the colors accordingly. The code would look as follows:

Dim a As Integer
Dim oneRow As Range

For a = 1 To rs.RecordCount 
    With ExcelSheet

        ''// show the row number in the first cell
        .Cells(a + 1, 1).Formula = "=ROW()"

        ''// set formatting to alternate row colors
        Set oneRow = .Cells(a + 1, 1).EntireRow
        oneRow.FormatConditions.Delete
        oneRow.FormatConditions.Add Type:=xlExpression, Formula1:= _
            "=MOD(ROW()-1, 2)=0"
        oneRow.FormatConditions(1).Interior.ColorIndex = 2
        oneRow.FormatConditions.Add Type:=xlExpression, Formula1:= _
            "=MOD(ROW()-1,2)=1"
        oneRow.FormatConditions(2).Interior.ColorIndex = 15

    End With
Next a
e.James
How do i manually enter in the row number?What about the number column? I dont want 1, 2, 3 to 2, 3, 1 when the rows are sorted.
masfenix
@edit, this was meant for someone else who commented, but deleted there comment. I will leave here for reference. I think I may have misguided you. This code is in Access, i create the document, all the formatting, the data is done through VBA on Access. Then i just call ExcelObject.save to save the file. If I number them from the Access DBA, thats fine but a user may open up the Excel sheet and re order the rows. Then since there is no macro in Excel, it will mess up the rows numbering
masfenix
Users are not very Excel-savvy. They just want to sort and print. Not one of them know a single line of code.
masfenix
I updated my code with a manually-entered title row number to match your example. This will retain its formatting even if rows are moved around, sorted, deleted, etc.
e.James
It was my deleted comment. Sorry, I missed that you are generating an Excel sheet from Access. This solution should work (or, alternatively, you could set up a basic template excel sheet and copy/edit that. That way, you can use the "conditional formatting" menu in Excel, rather than having to deal with `FormatConditions`)
BlueRaja - Danny Pflughoeft
Ah, I just noticed that you want the row number to change as well. I'll update with an answer to that, too.
e.James
There we go. I've tried out this code on my computer and it works as expected. Good luck!
e.James
Thankyou, I just had to `ROW() - 1` as the "data" starts from row 2 (but I dont want to count the title as row one) hope that makes sense. THANKYOU SO MUCH.
masfenix
No worries `:)`
e.James
I also had to modify some of your code as it wasnt working for me.` With oneRow .FormatConditions.Delete .FormatConditions.Add xlExpression, Formula1:="=MOD(ROW(),2)" .FormatConditions(1).Interior.ColorIndex = 15 End With`
masfenix
Wow this is so wierd, Access completely crashes on me when it gets to the second sheet (I have three sheets in my workbook)
masfenix
Even better. That looks simpler than my original, too.
e.James
I think it might be because I copy about 6000 records into the Excel sheet, and maybe after each row it copies it runs the formulas? so maybe its not crashing ,just taking forever. I'll test.
masfenix
It is because of that, my time to generate the report went from 25 seconds to almost 2 minutes. i think im gonna have a talk with the boss.
masfenix
You can apply all of that conditional formatting in one step to improve the speed. Just create a range containing all of the rows you have added, and apply the format to that range, outside of the loop.
e.James
Hi, please check my answer
masfenix
@masfenix: I have added my answer below your answer. This is now a much more efficient piece of code!
e.James
A quick note about the calculation issue: you can turn automatic calculation off while adding your data, and then turn it back on afterwards. See http://www.automateexcel.com/2004/10/31/excel_vba_turn_on_turn_off_calculation/
e.James
+1  A: 

@e.James

Dim rowRange As Range


ExcelSheet.Cells(1, 1).EntireColumn.ColumnWidth = 4
ExcelSheet.Cells(1, 1) = "#"
Set rowRange = Range("2:2", rs.RecordCount & ":" & rs.RecordCount)
rowRange.Select
With ExcelApp.Selection
    .FormatConditions.Delete
    .FormatConditions.Add xlExpression, Formula1:="=MOD(ROW(),2)"
    .FormatConditions(1).Interior.ColorIndex = 15
End With

That dosnt work. It just highlights the very top row (the title row) grey.

EDIT NEVERMIND Its supposed to be

Set rowRange = ExcelSheet.Range("2:2", rs.RecordCount & ":" & rs.RecordCount)

EDIT NUMBER 2: Do you know how I can insert the row numbers in each row using this method?

ANSWER:

ExcelSheet.Cells(1, 1).EntireColumn.ColumnWidth = 4
Set RowRange = Range("2:2", rs.RecordCount & ":" & rs.RecordCount)
RowRange.Columns(1).Formula = "=ROW()-1"
With RowRange
    .FormatConditions.Delete
    .FormatConditions.Add xlExpression, Formula1:="=MOD(ROW(),2)"
    .FormatConditions(1).Interior.ColorIndex = 15
End With
masfenix
answered in-line
e.James
oh my god, that was so easy lol. Maybe its the end of the workday and im just missing my caffeine.
masfenix
It also brought my time down from 25ish seconds to 10 - 13 seconds taking away 3 loops
masfenix
Glad to hear it!
e.James