Spacing One Picture per Page - excel

I am currently having to attach many pictures (jpeg) to an excel document and exporting it as a pdf. I need one picture per page.
I was using the following code, but with no avail.
For j = 0 To i
Cells(2, 1).Activate
Let pm = "Q:\Public\ACCE LINEAR\IRAD Photomics\A 350 Frame Photomics " & dat & "\" & sn & "\PHOTOMICS" & j & ".jpg"
ws1.Pictures.Insert(pm).Select
incr = 660 * (j + 1)
Selection.ShapeRange.IncrementTop incr
Next j
I activate Cell A2 so that the picture will initially be placed in the same spot every time. I then move the picture down a certain amount as defined by the variable "incr". At first I toyed with that number (660) until it worked and then went on to the next report. The problem is that what works for one report doesn't work for another.
I find this surprising as I have my print area (I believe that dictates the length of a page) set to incorporate all columns. Although each report has a unique amount of rows, they each have exactly the same amount of columns. Therefore, the print area should be the same from sheet to sheet and each picture is exactly the same size so that number shouldn't have to change from report to report.

I still don't understand why my previous spacing idea didn't work when the print area from sheet to sheet is exactly the same. However, knowing the print area is the same I instead made the top left cell in each page active and inserted each picture into that cell. This ensured that the pictures did not get cut when the excel file was exported as a PDF.
Here is the code I used. There are a few variable that were defined earlier in the code, but you should get the idea
b = counter - 1
For j = 0 To b
a = j + 1
If i > 24 Then a = j + 2
incr = (42 * a) - j
Cells(incr, 1).Activate
ws1.Pictures.Insert(MyFolder & "\" & PMArray(j)).Select
Next j

Related

How to add 2 jpeg pictures from excel in the same cell of a table in word document?

I am trying to add few jpeg pictures (up to 6) from excel worksheet in a table (word document), but only one appears at the end. Each time I am adding a picture it goes over the previous one. Here a part of my code with the issue:
' Filling the table
For i = 1 To iNumChem
' Column 1
wdTable.Rows(i + 1).Cells(1).Range.Text = Sheet1.Cells(a + 1 + 2 * i - 2, 5).Value
' Column 2
wdTable.Rows(i + 1).Cells(2).Range.Text = Sheet1.Cells(a + 1 + 2 * i - 2, 31).Value
' Column 3
For p = 0 To 5
If Sheet1.Cells(a + 2 * i, 5 + 2 * p).Value <> 0 Then
Sheet3.Shapes(Sheet1.Cells(a + 2 * i, 5 + 2 * p).Value).Copy
wdTable.Rows(i + 1).Cells(3).Range.PasteSpecial
End If
Next p
' Column 4
Next i
I tried to work with the properties ParagraphFormat and Move, but it didn't help.
I usually find difficult to move "the cursor" to the right position to be able to add something, especially in this case with Pictures (not Shapes) to add side by side.
Any ideas/comments are welcome.
Note: Edited after comments as I mixed the terms shape and picture!
I am trying to take pictures from Excel and add them in the same cell of a table word.
When you paste the shape it won't be in the cell, it will be anchored to it but float above it. This is just the same as in Excel where the shape floats above the worksheet and hides the cells below it.
To have the shape in the table you'll need to set the wrap type to inline, otherwise the shapes will stack up on top of each other.
With wdTable.Rows(i + 1).Cells(3).Range
.PasteSpecial
.ShapeRange(1).WrapFormat.Type = wdWrapInline
End With
EDIT:
Pictures are pasted into Word as InlineShapes. They do not stack up one on top of the other. If you attempt to paste more than one into wdTable.Rows(i + 1).Cells(3).Range each one will overwrite the last. Instead you need to declare a variable outside the loop, something like wdCellRange as Word.Range, and then use it when inserting the pictures, e.g.
Set wdCellRange = wdTable.Rows(i + 1).Cells(3).Range
With wdCellRange
.Collapse Direction:= wdCollapseEnd
.PasteSpecial
End With
You could try:
...Range.Collapse Direction:= wdCollapseEnd

Issue with nested for loops in VBA

I'm working on a project in Excel that helps a club here on campus allocate money to various other clubs. Anyways, I'm attempting to implement a macro-assigned button to allow the club to generate a new sheet that summarizes the event name, and the funding granted to the event.
The issue I'm currently stuck on is assigning 12 rows of data on this new sheet, for each club listed in the 'Summary' tab. I have the formula so that it cycles through the summary tab and inputs the club name down, but it continually inputs these names into cells A1-A12, rather than adding 12 new rows for the next club.
If my wording is confusing to follow; I want club 1's data to be in cells A1-12, club 2 in A13-24, etc.
I'm relying on nested for loops to try and cycle through and create these rows. Here's the part that's giving me trouble:
For k = 0 To 200 Step 12
'J is used to get names off the 'summary' tab
For j = 8 To Sheets.Count
'I is used to select cells 'a1' to 'a12'
For i = 1 To 12
Range("A" & (k + i)).Select
ActiveCell.Formula = ("=Summary!$A$" & j)
Next i
Next j
Next k
I'm certain my problem lies in the fact that j is advanced further before k, meaning it will continue to see k as 0 and input the new club's name in a1-a12, rather than stepping it up 12 BEFORE j is advanced. Whenever I try to insert next k above next j, I'm given an error.
This nested for loop is messy and is starting to make my brain hurt- but I can't seem to figure out a better way to tell Excel to skip 12 rows at a time. If anyone has any input or ideas on how to execute this macro in an easier way- let me know :-)
Try this code. There is no need to select cell before writing formula in it...
For j = 8 To Sheets.Count
For i = 1 To 12
Range("A" & ((j - 8) * 12 + i)).Formula = ("=Summary!$A$" & j)
Next i
Next j

Macro to Group Rows Throughout Excel Document

I have looked around and I feel like I am going crazy for not understanding how to do this, or what to do. It seems simple and yet I cannot figure out the best method.
I have an excel document that has 8 rows of data and that is supported by individual data from individuals that is 16 rows long. In total, there are 600 individuals in the dataset.
I was trying to locate a macro that would simply allow me to group every 16 rows in my excel sheet together. Whatever I have tried though, has not worked.
I am using Microsoft Excel 20116 for mac.
Range("1:16").Select
Selection.Rows.Group
Range("17:32").Select
Selection.Rows.Group
Repeat!
If there is a predictable data pattern (i.e. always exactly 16 rows) you might wish to put this inside a loop, where Range.Select is offset a further 16 rows each time.
For example:
i = 1
j = 16
While i < "YOUR UPPER LIMIT"
Range(i & ":" & j).Select
Selection.Rows.Group
i = i+16
j = j+16
Next
Note that if you group contiguous rows without a break, your groupings will automatically combine. You will need to play around with the line Range(i & ":" & j).Select to either use i+1 or j-1 depending on what you want as your display row on the grouping.

Retaining original table formatting after a 'pagebreak'

So here's the finished product, a statement of accounts with a working statement table, and an ageing analysis:
Everything works great. It basically populates itself row by row with data from another table. Here is the sample code:
j = 21 'First row on the statement of accounts workbook
For k = 1 To TSOA.ListRows.Count 'TSOA is the original data table
If Not TSOA.DataBodyRange.Rows(k).Hidden Then 'excludes the filtered entries
SOAwb.Worksheets(1).Cells(j, 4) = TSOA.DataBodyRange(k, 6) 'Debit
SOAwb.Worksheets(1).Cells(j, 5) = TSOA.DataBodyRange(k, 7) 'Credit
SOAwb.Worksheets(1).Cells(j, 1) = TSOA.DataBodyRange(k, 3) 'Date
<some other similar code goes here>
j = j + 1 'forces next row
If (j + 4) Mod 50 = 0 Then 'Increase footer, since there are only 50 rows in a page
j = j + 12 'Increase header
End If
End If
Next
So I coded in a 'somewhat' dynamic pagebreak, using the line of code:
If (j + 4) Mod 50 = 0 Then
j = j + 12 'Increase header
End If
where (j + 4) is the trigger for the footer pagebreak, Mod 50 divides (j+4) by 50 and gives you the remainder. Hence if its perfectly divisible, the result = 0.
j + 12 helps to skip past the header logos, you'll understand why in the next picture.
So the line of code basically works if you didn't care about the subsequent table formatting: ><
So does anyone know how do I continue with the previous table's formatting, ie the green and white statement table in the original page in the second page? Or is there some way to preload the table formatting in the second page (bearing in mind that not all statements need a second page). Or perhaps even tinkering about the print settings when the pagebreak triggers? Or any other creative solutions?
I have had zero experience with dealing with multiple pages using VBA, and quite frankly, I do not even know how to go about navigating between pages. I can't stress hard enough that this code is my amateur attempt to do useful things with excel, so there must be room for improvement!
Just change the page margins and the top few rows get excluded, but the manual page break is still required though!

Generated Data Label values from worksheet sometimes don't show

I am generating values in Excel 2010, initially putting them into an array, then copying them into a worksheet for use as datalabels for a logarithmix x-axis (actually calling Chart Labeller to do that, but this also happens when i manually apply through Excel). For the most part this works fine without problems. In certain instances, however, some, but not all, of the data labels do not visible show, even though the data in the worksheet is there, manually selecting the data labels shows an invisible label selected.
What I found out, and I think this may be a bug in Excel, when I go to the worksheet, and re-type in the value that is not showing up on the chart, it then shows up on the chart.
Here are my dim's for the array:
Dim chart_labeler_info_x()
Here is how I populate the array:
'Assuming we are going to do the x-axis
ReDim chart_labeler_info_x(1 To x_axis_interval_num, 1 To 3)
For k = 1 To x_axis_interval_num
'Column 1 is the new chart label value, column 2 is the y value of the new series , column 3 is the x value(equivalent to 111...)
'--------------------------------------------------------
chart_labeler_info_x(k, 1) = suf_ize(10 ^ (Log(x_axis.MinimumScale) / Log(10#) + (k - 1)))
chart_labeler_info_x(k, 2) = y_axis.MinimumScale
chart_labeler_info_x(k, 3) = 10 ^ (Log(x_axis.MinimumScale) / Log(10#) + (k - 1))
'--------------------------------------------------------
Next k
Here is how I initialize the range on the worksheet:
Set new_labeler_ws_x_axis = Sheets.Add
new_labeler_ws_x_axis.Name = Chart_for_series & "Eng_Labels_X_Axis"
new_labeler_ws_x_axis.Range("a1:c" & x_axis_interval_num).Value = chart_labeler_info_x
new_labeler_ws_x_axis.Range("a1:c" & x_axis_interval_num).Font.Name = "Arial"
new_labeler_ws_x_axis.Range("a1:c" & x_axis_interval_num).Font.Size = 7
I also create a new series attached to this range:
With ActiveChart.SeriesCollection.NewSeries
.XValues = Sheets(new_labeler_ws_x_axis.Name).Range("C1:C" & x_axis_interval_num)
.Values = Sheets(new_labeler_ws_x_axis.Name).Range("B1:B" & x_axis_interval_num)
.Name = "=""Labeller_x"""
.Border.Color = RGB(0, 0, 0)
.Format.line.Visible = True
End With
The data that is generated in the worksheet looks like this:
1m 100 0.001
10m 100 0.01
100m 100 0.1
1 100 1
10 100 10
100 100 100
1k 100 1000
Column 1 has the values that will be used as the new data labels. Column 2 is the y-value, Column 3 is the actual x-value. (I can attach the worksheet if that helps.)
Here is an image of what I am talking about:
You notice that the 1k data label that should be there, is not visible.
I can make the 1k data label appear one of two ways:
Extend the maximum value for the series, in this case to 10,000 (10k) in which case the 1k label shows.
Manually go to the worksheet, select the cell that has the 1000 value, re-enter the value 1000 and press return, the data label then shows up as 1k.
Some other interesting anomalies, when the maximum value is 100, the data label for 100 disappears also. As the maximum value is increased beyond 1000, there seems to be no problems the data labels all show themselves.
I have tried changing the number format, which general, to number, with two decimal places, no luck. Changing to text and back, no luck.
I think this is a bug, but haven't found in info, can any of the experts out there shine some light on this?
I found a solution, while somewhat of a hack, i think it underlines what the problem may actually be, and maybe someone can suggest a more elegant solution.
I added the last line of this code block:
chart_labeler_info_x(k, 1) = suf_ize(10 ^ (Log(x_axis.MinimumScale) / Log(10#) + (k - 1)))
chart_labeler_info_x(k, 2) = y_axis.MinimumScale
chart_labeler_info_x(k, 3) = 10# ^ (Log(x_axis.MinimumScale) / Log(10#) + (k - 1#))
'This line did the trick
If chart_labeler_info_x(k, 3) >= 1 Then chart_labeler_info_x(k, 3) = Round(chart_labeler_info_x(k, 3), 0)
As i said previously, we had found that manually updating the value in the cell, caused the labels to be visible. We tried applying the Round function to the value in the cell, and that worked, so i put it as a check in the code, for values of 1 and higher.
It appears that, even though the cell value shown is 1000, internally, it must not be. (I checked .value and .value2, they both reported 1000.) The bug i think lies in this happening SOMETIMES. If the maximum value of the series is increased, the 1k label appears, even though it it the same math being used to generate the values.
Maybe someone can explain why this is happening and offer a more elegant solution!
Thanks,
Russ

Resources