PowerPoint/Excel VBA - Change default range of data for a chart - vba

I want to be able to use my own Excel Workbook to create a pie diagram in PowerPoint. So far, I have created a VBA script to add the chart. I also changed the data sheet for the chart to look like this:
Problem
Following core problem remains:
I can't figure out, how to dynamically define the data range of the chart's data source sheet
Because the default values for the pie chart belong to these ranges, PowerPoint sets those ranges by default. If my data sheet contains more (or equal to) than 4 rows of data, it won't be that bad, as the range automatically increases. However, as shown in the example, the range doesn't adapt when there are only 3 rows of data.
What I want, would look like this: Needed (I only know how to get the data in the correct place, but not how to select it)
Related VBA code is below:
Set diaPie = pres.Slides(3).Shapes.AddChart2(2, xlPie).Chart
Set pieChartData = diaPie.ChartData
Set pieWorkbook = pieChartData.Workbook
Set pieWorksheet = pieWorkbook.Worksheets(1)
pieWorksheet.UsedRange.Clear
With dataWorksheet
id = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
a = dataWorksheet.Range("A1", dataWorksheet.Range("A1").Offset(id, 0))
b = dataWorksheet.Range("B1", dataWorksheet.Range("B1").Offset(id, 0))
pieWorksheet.Range("A2", pieWorksheet.Range("A2").Offset(id, 0)) = a
pieWorksheet.Range("B2", pieWorksheet.Range("B2").Offset(id, 0)) = b
Thanks in advance!

This should change the data range on your data sheet. maxrow is just the end of the data. So if your data is in B1:B4 then maxrow would be 4
diaPie.SeriesCollection(1).values = "Sheet1!$B$1:$B" & maxrow ' change the series range before opening and closing the workbook object
diaPie.SeriesCollection(1).XValues = "Sheet1!$A$1:$A" & maxrow 'Labels

Related

How to fill cell with data from a separate worksheet in excel?

I am attempting to match 2 columns in two separate worksheets and then fill data from worksheet 2 in worksheet 1.
I need to match Column A(Worksheet 2) to Column D(Worksheet 1). Once Matched I need to fill Column F(Worksheet 1) with the data from Column B(Worksheet 2). Once data is populated I would also like to change the color of Column F(Worksheet 1) based on the data that is present. Worksheet 1
Worksheet 2
Put this in F2 On Sheet 1, update the sheet name Sheet2 to whatever your second sheet is named, then copy down:
=VLOOKUP($D2,Sheet2!$A:$B,2,FALSE)
Then you can apply conditional formatting to Column F on Sheet 1.
If you might have values in Sheet 1 that aren't in Sheet 2, this will handle the error:
=IFERROR(VLOOKUP($D2,Sheet2!$A:$B,2,FALSE),"Not Found!")
[Updated for additional question about spanning accross workbooks]
For another open workbook, use the following and replace [Book2] with the path of the second workbook or the name of an open workbook:
=IFERROR(VLOOKUP($D2,[Book2]Sheet2!$A:$B,2,FALSE),"Not Found!")
Also note, Excel will automatically build all of the references if you select them manually while building the formula in the formula bar: Excel Formulas Overview on MSDN
More information is needed to provide you with an exact code but here is a good start
'Assuming there are 10 rows in each worksheet
dim i as integer
dim j as integer
for i = 1 to 10
for j = 1 to 10
if sheet1.cells(i,4).value = sheet2.cells(j,1).value then
sheet1.cells(i,6).value = sheet1.cells(j,2).value
sheet1.cells(i,6).interior.color = vbyellow
end if
next j
next i
the color can also be controlled with the rgb function, simply replace the vbyellow in the above code:
For example rgb(255,204,255) will be a light pink

excel vba: creating a range without referencing a sheet

I would like to know if I can save a generic range, without it having a sheet name attached to it?
Lets say that my program creates a sheet for every day of the week, and then makes headings for every sheet. I want to give it a few ranges, and it must merge and add different headings to those ranges in EVERY sheet. So the headings of every sheet looks the same.
I have the following range for example:
...
Set rowTwoHeadingKiloRange = Range(Cells(2, 4), Cells(2, 8))
Set rowTwoHeadingUnitRange = Range(Cells(2, 10), Cells(2, 14))
...
Now when I try to pass this range in a dictionary to every sheet that gets created, I find that I have undesired results as some of the headings gets created on sheets where they do not belong (And I think that is because when the range is created, it attaches to the active sheet at that moment - which may be different from time to time).
So now I basically have a function that looks something like this...
Public Function colmHeadingsAndSpacing(sheetName)
With Worksheets(sheetName)
...
Set rowTwoHeadingKiloRange = Range(Cells(2, 4), Cells(2, 8))
Set rowTwoHeadingUnitRange = Range(Cells(2, 10), Cells(2, 14))
...
End with
End Function
... and I run the function every time I create a sheet, with the name of the sheet that was just created given through. But this runs the function 7 times, when I use the same data (range) every time. Also I feel that it is not working properly as well (I still get strange reactions - ranges ending up in wrong sheets).
Second question, is there a way to find out on a range, what sheet is "attached" to the range. Something like: msgbox rowTwoHeadingKiloRange.worksheets.name which will give the result of Sunday
You were close. To attach your Range and Cell to the With statement you need to use a full-stop . before the keyword. Like this:
Public Function colmHeadingsAndSpacing(sheetName)
With ThisWorkbook.Worksheets(sheetName)
...
Set rowTwoHeadingKiloRange = .Range(.Cells(2, 4), .Cells(2, 8))
Set rowTwoHeadingUnitRange = .Range(.Cells(2, 10), .Cells(2, 14))
...
End with
End Function
This is good practice to qualify every range reference with it's attached worksheet. I went one step further included a workbook reference (ThisWorkbook). Now it's fully qualified.
For the second question -- try MsgBox rowTwoHeadingKiloRange.Parent.Name to get the name of the worksheet. It's usually better to start with the worksheet name rather than work back to it though.
A range is a reference of a (mostly rectangular) area on a sheet. So referring to a range without defining a sheet like Set r = Range ("B2:F10") is exactly the same as Set r = Activeworkbook.Activesheet.Range ("B2:F10"). So for more professional purposes VBA offers you the flexibility in the following way:
Dim wb As Workbook
Dim ws As Worksheet
Set wb = Workbooks.Add ' open new xlsx file
Set ws = Activesheet OR
Set ws = wb.Activesheet OR
Set ws = wb.Sheets(1)
' do something else here and later when neither wb nor ws is active, you can
Set r = wb.ws.Range("B5:G22") OR
Set r = ws.Range("B5:G22")
An addition: for producing a number of sheets of the same format, you may consider using templates either. Then you need to fill in only the differences programatically. Less programming, easier maintenance :)

Copying Row Except Last Column in VBA

I am writing an Excel VBA macro and one of the tasks is to copy a subset of the data from a sheet to another.
I currently use the below, which copies the whole row fine (C is a row index):
Dim ConsolidatedRow As Excel.Range
Set ConsolidatedRow = ConsolidatedSheet.Range("A" & C).EntireRow
...
ConsolidatedRow.Copy Destination:=ResultSheet.Range("A" & ResultRowIndex)
I want to copy ConsolidatedRow, but without the last column. This last column is used in other operations between declaration and copy so the ideal solution would be a change to the copy statement. I've tried offsets, updating the range in ConsolidatedRow and loads of other things but no luck.
I prefer to use the Range.End property to locate the last used cell. Helps out if your row doesn't extend out as far as others in your sheet. Replace the Set ConsolidatedRow command with the following:
With ConsolidatedSheet
CopyExtent = .Range("A" & C).End(xlToRight).Column - 1
Set ConsolidatedRow = .Range(.Cells(C, 1), .Cells(C, CopyExtent))
End With
This assumes you have no gaps in your data. If you have blank cells that you want included in the copied section, change to this:
CopyExtent = ConsolidatedSheet.Cells(C, .Columns.Count).End(xlToLeft).Column - 1
Hope this helps!
Assuming that you don't use columns behind this consolidatedRow in this worksheet, add two lines after set
Set ConsolidatedRow = Intersect(ConsolidatedSheet.UsedRange, ConsolidatedRow)
Set ConsolidatedRow = ConsolidatedRow.Resize(1, ConsolidatedRow.Columns.Count - 1)

Copying one sheet to another workbook based on one criteria

I have 2 different workbooks, main and copy.
Row 1 is meant for header/labeling the information it will be providing for both workbooks.
The "main" workbook will be using columns A to N. The copy will be using columns A to M.
The criteria to determine whether the code will be copying is the workbook, "main", column M.
If the cell contains "X" - it will copy column A to L, and N, to the workbook "copy". After which, it will go on to the next row to determine the same thing.
If the cell is empty, it will proceed down to the next row to determine the same thing as well.
The code has to be dynamic as new information will be added every 3 months, such as new rows added or the criteria changing from "X" to empty, or empty to "X".
I am a beginner in VBA excel, and have been trying out multiple codes but it doesn't seems to work. Would greatly appreciate it if someone could help me out with this.
Showing your code so far will help us a lot.
Maybe this helps a little:
Dim wks As Worksheet
Dim wks_copy As Worksheet
Set wks = Worksheets("main")
Set wks_copy = Worksheets("copy")
j = 2
For i = 2 To wks.UsedRange.Rows.Count
If wks.Cells(i, 13).Value = "x" Then
wks.Range(Cells(i, 1), Cells(i, 14)).Copy Destination:=wks_copy.Cells(j, 1)
j = j + 1
End If
Next i
This will copy the entire row. If you don't want to copy column M, I suggest clearing or hiding the column after copying.
If the macro runs again after 3 months, it will overwrite the existing data on Worksheet copy. But you should delete the worksheet's values before that, for example by using
Worksheets("copy").UsedRange.Offset(1, 0).ClearContents
or manually clearing the range.

Move data from every X column into single column in Excel

Problem Solved using modifications to answer
Dim i As Long, values As Range, current As Range
Set current = Range("D4") '//select 1st anchor cell
Do Until current.Value = ""
i = i + 45
Set values = Range(current.Offset(2, 0), current.Offset(45, 0)) '//select all in the ooc column
values.Copy '//got block of data here
Sheets("Sheet1").Range("A" & i).PasteSpecial
Set current = current.Offset(0, 13) '//next page
Loop
Starting in column C of an excel spreadsheet, I have pages of data 13 columns wide. I need to transfer the data in the 2nd and 3rd columns to a SQL Database, so I'm trying to move those 2 columns on each page on top of eachother for transfer.
The Screenshot below is the data im working with. I need to capture server names under ODC CSS Servers RowX CabX along with its corresponding asset tag. If i can just take those 2 columns every 13 rows and stack them I can delete the extra information on my own.
Spreadsheet http://img830.imageshack.us/img830/6126/unledoks.png
I'm sure I don't need to mention the insane amount of time this would save but I could really use some help getting started with, or using an example macro to accomplish this. I don't have much for VBA experience unfortunately, but I will work with what help I can get.
What about;
dim i As Long, values as range, current As range
set current = Range("D4") '//select 1st anchor cell
do until current.Value = ""
i = i + 1
set values = range(current.offset(1, 0), current.End(xlToRight)) '//select all in the ooc column
values.copy '//got block of data here
sheets("someothersheet").range("A" & i * 2 - 1).pastespecial
set current = current.offset(0, 13) '//next page
loop