Offset problem

Les Isaacs

Registered User.
Local time
Today, 21:17
Joined
May 6, 2008
Messages
186
Hi All
I have a routine in an access module that writes an excel workbook with some very specific data, validation and formatting etc. Most of it works fine, but why doesn't this work?
Code:
1090          For inc = 0 To 23
                  'With objSheet.range("AM7:BB7").Offset(0, ColOffset)
1100              With objSheet.range("AD" & lngRowCount & ":AD" & lngRowCount + 1).Offset(0, inc)
1110                  .MergeCells = True
1120                  .WrapText = True
1130              End With
1140          Next
It works while 'inc' is zero (so column AD gets the merge/wrap), but not for any other values.

The 2nd line (commented out) is just there because I have used that syntax elsewhere, and it works :banghead:

'inc' is defined as an integer.

Hope someone can help - this is driving me nuts:eek:
Thanks
Les
 
Last edited:
I'm not familiar with Offset syntax but I will hazard a guess that VBA is confused with the mixed concatenation and addition.

Try
objSheet.range("AD" & lngRowCount & ":AD" & (lngRowCount + 1)).Offset(0, inc)
 
Hi Cronk
Thanks for your suggestion. I tried the extra brackets, but sadly no joy :(

Hi Brian
Thanks also for your link: very interesting, but I don't think that's it in my case though, because I'm not trying to do anything with the merged cells afterwards so don't need to change the size of the range. Also, my syntax works fine with the other (commented out) line, where the range address is hard-coded rather than partially supplied as a parameter (lngRowCount) :banghead:
From the thread it does seem though that merge and offset are not happy companions :eek:

If you - or anyone else out there - has any other ideas I'd be really grateful.

Thanks again.
Les
 
OK, I've now looked up the syntax.

There has to be a Select after the Offset to select the range as in
With objWS.Range("AD" & lngRowCount & ":AD" & (lngRowCount + 1)).Offset(0, inc).Select
 
Cronk
Now that looks interesting!
I won't be in the office until Monday (it's Sat night here - UK - where are you) so won't be able to test your syntax until then: but my intuition leads me to be hopeful :cool:
Cheers - I'll let you know.
Les
 
Cronk
Adding the extra brackets round (lngRowCount + 1)) had no effect.
Adding the .Select to the end of the statement gave me an "Object required" error :mad:
Am I going to have to have 23 separate statements, instead of the loop?
Hope for any more ideas :o
Thanks again.
Les
 
Not sure if this will help, but like eating chicken soup when one has a head-cold, "it couldn't hurt"
This is a "scratch pad code" I use to past and modify reports generated with Excel VBA. It is based on the number of records returned in a record set intMaxRecocord count. All of my Excel reports start at Row 5 (intRowPosition) so the maximum count will be the Number of Records Returned from the recordset + intRowPosition.

What this code does with the offset method. The Data is sorted by Name then by Transaction Date. Of course there may be other columns in-between.
The first time a Name appears - (i.e. the latest transaction) use the offset to Bold specific columns for that row.
Then, for the rest of the repeated names lighten the fonts for specific numbers of columns.
This formatting allows users to see the first use of a Name in bold.
While this uses Bold, in your case, just use the wrap text or other formatting.

This is a Conditional Formatting based on values. Yours may not need the IF statement.

The Resize method is very powerful. It can even be used against the original cell. Remember this if you ever need to change Excels format type. If your Query for example returns the Text value of 5 and you need Excel to change it to the Numeric value of 5. It is used for just about any formatting.

For more details, look at http://www.access-programmers.co.uk/forums/showthread.php?t=249670

An offset example of the sum-total method in Array format is at:
http://www.access-programmers.co.uk/forums/showthread.php?t=240342
And a good basic reminder of sending a DAO recordset to Excel is at:
http://www.access-programmers.co.uk/forums/showthread.php?t=149974
Where the offset moves off the header row.

Example:
Code:
1340      ObjXL.Range("B" & intRowPos & ":B" & intMaxRecordCount + (intRowPos)).Select ' changed this to A for this report
         'Debug.Print intRowPos & " start to end " & intMaxRecordCount
          ' Row B has names in order then transaction dates in order
          ' If Row B - bold the first x columns for a new name, lighten up the repeats 
1350      For Each c In ObjXL.ActiveWindow.Selection
1360      If c.value <> c.Offset(-1, 0).value Then ' look at value below it
1370          c.Font.FontStyle = "Bold"
              'c.EntireRow.Font.Bold = True
1380          c.Resize(, 2).Font.Bold = True ' bolds 2th columns out all Comments should be bold - try -1 for column A to be bold too
                
1390      Else
1400          'c.Font.ThemeColor = xlThemeColorLight1            'xlThemeColorDark1
                ' Win 7 turns white on line above and below - comment out for now
1410          'c.Font.TintAndShade = 0.349986267
              'c.EntireRow.Font.ThemeColor = xlThemeColorLight1    'xlThemeColorDark1
                'c.EntireRow.Font.TintAndShade = 0.349986267
              'c.EntireRow.Font.TintAndShade = -0.249977111
              'c.Resize(, 13).Font.ThemeColor = xlThemeColorDark1
              'c.Resize(, 13).Font.TintAndShade = -0.549977111   ' lighten up repeat rows 5 columns out changed from -0.249977111 to make a little darker
              ' This next line should reach out and clear the second Stip as requested
              'c.Resize(, 9).Font.Bold = True ' Reached out and bolded the 9th  column ' this can reachout and bold every item in one column if needed
              'c.Parent.Cells(c.ROW, 31).ClearContents   ' removes Stip codes if it is a repeated record
1420      End If
1430  Next c
1440      ObjXL.Range("B" & intRowPos & ":B" & intMaxRecordCount + (intRowPos)).Select ' changed this to B for this report
1450      For Each c In ObjXL.ActiveWindow.Selection
1460      If c.value <> c.Offset(-1, 0).value Then
              'c.Font.FontStyle = "Bold"
              'c.EntireRow.Font.Bold = True
              'c.Resize(, 1).Font.Bold = True ' bolds 2th columns out all Comments should be bold - try -1 for column A to be bold too
1470          c.Offset(, -1).Resize(, 1).Font.Bold = True      ' This takes change in Pad Name - offsets left and bolds range 
1480      Else
1510      End If
1520      Next c

1530      Set c = Nothing
 
Have you set objSheet? I wonder if you copied the original code from VBA, why the .range is not .Range

Otherwise, post the whole code in that routine.
 
Hi Rx
Thanks for your comprehensive post! I have to say that much of it was a bit beyond me :o , and I couldn't quite see whether what you've done applies to my situation. I do appreciate your help though.

Hi Cronk
Yep - I have
Code:
Set objSheet = objBook.Worksheets("All Staff")
at the head of the procedure. Not sure why .range hasn't been capitalized - but there are tons of others the same, and they all work :)
The complete routine is quite long - but I have uploaded, since you asked :D
The problem loop is at line 1090 (now commented out, and replaced with lines 1090 to 2040 :eek: .
It would be great if I could get this to work with the loop, as I have other similar issues in other modules that could benefit from the same approach.
Cheers
Les
 

Attachments

As I currently don't have a machine I cannot test anything, this is being typed on an iPad, but I really do think that you need to use the resize function as in the link I posted and in RX s code. Another approach might be to index the range using Cells(row number, col number) but as I can't play with this I'm flying a bit blind.

As I don't use merge, or perhaps should say didn't, I cannot appreciate why merging ad then ae then af is different to just merging af.
Must have a play when I get my new machine.


Brian
 
Hi Brian

OK - I will try again to fathom Rx's code to see if the resize function will do the trick. I am surprised that this is being suggested though, because I had thought that resize would just have changed the dimensions of cells, whereas I need to merge them, which is different - or is it :confused:

When you say about merging ad then ae then af being the same as just merging af, maybe I'm missing something: I want to merge AD3 with AD4, AE3 with AE4, then AF3 with AF4, etc. - so I end up with 3 pairs of merged cells (in fact I need 23 pairs :eek:). I need to do this for successive pairs of rows (held by lngRowCount in my code), and I need to do it on two separate sheets in which the actual column addresses are different (hence ColOffset in my code).

Does this make sense - or am I on completely on the wrong track :o

Thanks again
Les
 
It's probably me trying to get my head round it without being able to see it.

Resize is used to resize ranges which now that you have explained in English I now don't think applies to you. I think I would look to index my ranges using Cells(rownum, colnum)

Brian
 
I have just realised that you are merging rows, I didn't know you could do that.

I would think of concatenating the data rather than doing the cell merge , but then I never liked merged cells.

Brian
 
OK, the code you posted helped. With out the data, this was written for column A, B going out from there. It runs in Excel if you put data in Row A9:G9. It will offset then select the cell below, merge the two and wraptext.
If Row 10 has data, it will error because merging two cells with data does that kind of thing.
You have a good grasp of object code to make this work for you.

Hope this helps
Code:
Public Sub test2()
Dim Inc As Integer
Dim ColOffset As Integer
Dim lngRowCount As Long
lngRowCount = 9
ColOffset = 3
Sheets("Sheet1").Range("A7").Select
            For Inc = 0 To 5
                  With Excel.Application.Range("A7:B7").Offset(0, ColOffset)
                    With Excel.Application.Sheets("Sheet1").Range("A" & lngRowCount).Select
                    ActiveCell.Select
                    ActiveCell.Offset(0, Inc).Range("A1:A2").Select
1100                    With Excel.Application.Selection
1110                        .MergeCells = True
1120                        .WrapText = True
1130                    End With
                   End With
                   End With
            Next
End Sub
Dont' get stuck on the "A1:A2" - that is just a relative cell for that range.
Tried to use your same variables with smaller values.

Regarding Resize, just an FYI

Code:
Sub test3() ' using resize in Excel
      ' select cell with data in the rectangular area of data
      ' The Current Region selects all of the data.
      ' Now add one extra row to that and select it for your next step
      Dim NumRows As Long
      Dim NumCols As Long
      Dim Cr As Range
       
10    Set Cr = ActiveCell.CurrentRegion
20    NumRows = Cr.Rows.Count
30    NumCols = Cr.Columns.Count
40    Cr.Resize(NumRows + 1, NumCols + 1).Select
End Sub
Sub test4()
' say you wanted to union non-contiguous areas and select them
' the resize is more powerful
10   Union(ActiveCell.Resize(5, 2), ActiveCell.Offset(, 5).Resize(5, 2)).Select
End Sub


The Resize might be considered as shown when using offset.
Hope that helps.
Code:
Sub Test7()
Dim myRange As Range
'   Set a range somehow for a placeholder
    Set myRange = Range("A15:G16")
    Range("G5:G8").Offset(0, -1).Resize(myRange.Cells.Count, 1).Select
    ' now F5 to F8 is selected
    With Selection
        .WrapText = True
    End With
End Sub
 
Last edited:
I was wondering if

With Objsheet.range("AD" & lngrowcount).offset(0,inc).resize(2,0)
.mergecells =true
Etc


Would work

Brian
 
Close. I put the example here that works in Excel, just substitute the object code for Excel object.
Added the Rows and Columns count so the example of Offset would be a little more self documented. The line 110 MyRange.Resize lends itself to some nice variable substitution.
Put this code in an Excel Module and step through it. Granted, it is more for demonstration than efficiency. Steps could be combined.

Code:
Public Sub test2()
      ' On Excel from A9:G9 - type in some long text in each
      ' this will highlight A9, select and merge the cell below it, then move to B9...
      Dim Inc As Integer
      Dim ColOffset As Integer
      Dim lngRowCount As Long
10    lngRowCount = 9
20    ColOffset = 3
      Dim numRows As Integer
      Dim numCols As Integer
      Dim MyRange As Range
30    Sheets("Sheet1").Range("A7").Select
40          For Inc = 0 To 5
50                With Excel.Application.Range("A7:B7").Offset(0, ColOffset)
60                  With Excel.Application.Sheets("Sheet1").Range("A" & lngRowCount).Select
70                  ActiveCell.Offset(0, Inc).Select
80                  Set MyRange = ActiveCell
90                  numRows = MyRange.Rows.Count
100                 numCols = MyRange.Columns.Count
110                 MyRange.Resize(numRows + 1, numCols).Select
                    ' MyRange.Resize(numRows + 1, numCols + 1).Select ' example for you
120                     With Excel.Application.Selection
130                         .MergeCells = True
140                         .WrapText = True
150                     End With
160                End With
170                End With
180         Next
End Sub
 
Rx_
You said close but if your code is made specific it confirms what I wrote.
We know that the resize is to 2 rows and no change in the columns, which I think is achieved with the 0.

I don't use select and selection techniques unless forced to .

Les what the code is doing is selecting the cell on the top row by offsetting from AD and then expanding the range to include the cell on the next row. What you were trying to do was make the offset work on both rows.

Brian
 

Users who are viewing this thread

Back
Top Bottom