Powershell Excel Chart - obtain data series from existing chart - excel

I have a Powershell script that copies a worksheet (with a custom dual axis chart) from one workbook to another workbook and then populates the new copy with data. That portion of the script works fine but I am trying to change the data series in the existing chart and I do not know the fields to change the data series.
I can change the chart title and the legend labels of the existing chart with no issues. I have tried the $ChartTemplate.SeriesCollection(1).Values field and the $ChartTemplate.SeriesCollection(1).XValues with and with out the $ChartTemplate.SeriesCollection().NewSeries.Invoke() command and I have had no success.
Does anyone know the Powershell syntax to edit an existing data series of a custom dual axis line chart (=SERIES(Template!$G$1,Template!$A$2:$A$112,Template!$G$2:$G$112,4) ?
The following is my Powershell code which I have obtained from googling:
$file1 = $global:ChartTemplateXlsx # source's fullpath
$file2 = $Path # destination's fullpath
$xl = new-object -c excel.application
$xl.Visible = $False # dont display the spreadsheet
$xl.displayAlerts = $false # don't prompt the user
$wb1 = $xl.workbooks.open($file1, $null, $true) # open source, readonly
$wb = $xl.workbooks.open($file2) # open target workbook/worksheet
$sh1_wb = $wb.sheets.item(1) # 1st sheet in destination workbook
$sheetToCopy = $wb1.sheets.item('Template') # source sheet to copy
$sheetToCopy.copy($sh1_wb) # copy source sheet to destination workbook
$ws = $wb.ActiveSheet # set the worksheet
$ChartTemplate = $ws.chartobjects(1).chart # obtain the existing chart
$ChartTemplate.HasTitle = $true # turn on chart title
$ChartTemplate.ChartTitle.Text = "Test Chart" # set a new chart title
$ChartTemplate.SeriesCollection(1).Name = "=""Test01"""
$ChartTemplate.SeriesCollection(2).Name = "=""Test02"""
$ChartTemplate.SeriesCollection(3).Name = "=""Test03"""
$ChartTemplate.SeriesCollection(4).Name = "=""Test04"""
$wb1.close($false) # close source workbook w/o saving
$wb.close($true) # close and save destination workbook
$xl.quit()
spps -n excel
By the way, I am using a separate workbook with the chart so that users can create their own chart templates and then I will populate it with data.

The property that you're looking for is either the Formula or FormulaLocal property. They appear to be duplicates of each other. If updating one doesn't work, try the other, or just set both.
$ChartTemplate.SeriesCollection(1).Formula = '=SERIES(Template!$G$1,Template!$A$2:$A$112,Template!$G$2:$G$112,4)'
$ChartTemplate.SeriesCollection(1).FormulaLocal = '=SERIES(Template!$G$1,Template!$A$2:$A$112,Template!$G$2:$G$112,4)'

Related

PowerShell: Format second sheet within xlsx file

PowerShell: Format second sheet within xlsx file
I am working with an xlsx file that has two sheets within it.
I am uploading data into these sheets and formatting it.
I am able to successfully format the first sheet but not the second sheet.
This is the code for how I format the first sheet:
# Format Data: Autofit Columns
$lgTime = "[{0:HH:mm:ss}]" -f (Get-Date)
Write-Host "$lgTime Autofitting Data Columns..."
$range2autofit = $worksheet.UsedRange
$rowCount = $range2autofit.Rows.Count
[void] $range2autofit.EntireColumn.Autofit()
$lgTime = "[{0:HH:mm:ss}]" -f (Get-Date)
write-host "$lgTime Creating Excel Table Format ..."
$tableStyle = "TableStyleMedium9"
$tableStyle = "TableStyleLight21"
$Worksheet.Columns.Item("A").NumberFormat = "MM/DD/YYYY"
$ListObject = $WorkBook.ActiveSheet.ListObjects.Add(1, $range2autofit, $null , 1, $null, $tableStyle)
I would like the same formatting to be applied to the second sheet within the file but am having trouble doing that. I have tried using that same code again but with small changes such as:
Workbook.Worksheet.Item(2).UsedRange
Workbook.Worksheet.Item("Sheet2Name").UsedRange
My thought process is that I should be able to use the same code but just access the second sheet in it, I think I am just not accessing the second sheet correctly. That could be completely wrong though.
Edit:
This is where I defined $workbook and added a sheet to the xlsx file which is followed by the renaming of each sheet
$dataFile = "FILE LOCATION.xlsx"
$objExcel = New-Object -ComObject Excel.Application
$objExcel.Visible = $false
$workbook = $objExcel.Workbooks.Open($dataFile)
$worksheet = $workbook.Worksheets.Add()
$worksheetOne = $workbook.Worksheets.Item(1)
$worksheetOne.Name = "Sheet1Name"
$worksheetTwo = $workbook.Worksheets.Item(2)
$worksheetTwo.Name = "Sheet2Name"
From the code you added in your edit, it looks like you're getting tripped up when adding a sheet, then using the wrong index later? Worksheets.Add() creates a blank worksheet at index 2 by default, not at the end. For example:
# A good way to check and see what you're doing with your sheets:
$workbook.Worksheets | select Index,Name
Index Name
----- ----
1 Sheet1
2 Sheet2
# add a new sheet
$worksheet = $workbook.Worksheets.Add()
# check again
$workbook.Worksheets | select Index,Name
Index Name
----- ----
1 Sheet1
2 Sheet3 # whoops!
3 Sheet2
To add before/after a specific worksheet instead, you can specify like this:
# missing value is required for COM functions
$newSheet = $workbook.Worksheets.add(
[System.Reflection.Missing]::Value, ## before index n
$workbook.Worksheets.Item(2) ## after index n
)
Then just be careful when you select your sheets, and you should be good to go!
# Setting sheet properties by referring to variable
$ws1 = $workbook.Worksheets.Item(1)
$ws1.Name = "Sheet1Name"
$ws1.UsedRange.EntireColumn.AutoFit()
$ws2 = $workbook.Worksheets.Item(2)
$ws2.Name = "Sheet2Name"
$ws2.UsedRange.EntireColumn.AutoFit()

Merge multiple excel files containing multiple sheets using Powershell

I am having multiple excel files having same no of sheets with same sheet names. The same sheets in all excel files having the same headers. So I want an idea how to do merging for all the matched sheets in multiple excel files and create a new excel file via scripting using Powershell.
Any sugguestion Helps.
Thanks.
If the number of columns is the same across the different Excel worksheets then you should be able to use the below code to merge the files together.
The code uses methods from the NamedRange interface from the Excel API.
Example Code: (Just remember to change the paths and file names to your environment)
# Create an instance of Excel
$Excel = New-Object -ComObject Excel.Application
# Find the files you want to process
$Files = Get-ChildItem -Path C:\Temp -Filter *.xlsx
# Create a target workbook and worksheet called 'Sheet1'
$TargetWorkbook = $Excel.Workbooks.add()
$TargetWorksheet = $TargetWorkbook.Sheets.Item("Sheet1")
# Loop through our Excel files
foreach($File in $Files) {
# Open the workbook and get the first sheet
$SourceWorkbook=$Excel.Workbooks.Open($File.FullName)
$SourceWorksheet=$SourceWorkbook.Sheets.Item(1)
# Calculate the end column letter
$EndColumn = [char]([int][char]'A' + $SourceWorksheet.UsedRange.Columns.Count - 1)
# Activate the source worksheet
$SourceWorksheet.activate()
# Get the total number of rows in the sheet
$SourceLastRow = $SourceWorksheet.UsedRange.Rows.Count + 1
# Calculate what our start row should be
# A1 for the first worksheet only to include the headers
$StartRow = (& { If ($TargetWorkSheet.UsedRange.rows.count -eq 1) { "A1" } Else { "A2" } } )
# Get the range of data and copy it to the clipboard
$SourceRange = $SourceWorksheet.Range("$($StartRow):$EndColumn$SourceLastRow")
$SourceRange.copy()
# Activate the target worksheet
$TargetWorksheet.activate()
# Get the total number of rows in the sheet
$TargetLastRow = $TargetWorkSheet.UsedRange.Rows.Count
if ($TargetWorkSheet.UsedRange.Rows.Count -ne 1) {
# If this isn't the first sheet we've processed, add one additional row
$TargetLastRow++
}
# Get the target range and paste the data
$TargetRange = $TargetWorksheet.Range("A$($TargetLastRow):$EndColumn$($SourceRange.Rows.Count)")
$TargetWorksheet.Paste($TargetRange)
# Disable showing alerts, otherwise a notification about
# large amounts of data on the clipboard will be shown
$Excel.DisplayAlerts = $false
# Close the source workbook
$SourceWorkbook.Close()
}
# Re-enable showing alerts
$Excel.DisplayAlerts = $true
# Save the workbook to the desired path
$TargetWorkbook.SaveAs("C:\Temp\Merged.xlsx")
# Quit Excel
$Excel.Quit()
If your sheets have different numbers of columns, you could still use the above code, however you'll need to make some changes to the $SourceRange, $TargetRange and $EndColumn variables to account for this.

Combining Multiple Workbooks Into One Workbook Worksheet With Powershell

I have this Powershell script i'm trying to combine multiple workbooks with single sheets onto one workbook with a single sheet and combine them all on the one sheet. I can't get past the fact it keeps telling me there is no file named $destfile and can't be opened. What is the correct syntax for that?
Thanks
$ExcelObject = New-Object -ComObject excel.application
$ExcelObject.visible=$true
$file1 = 'file1location'
$file2 = 'file2location'
$destfile = 'fileI want to saveas afterits compiled'
$xl = new-object -c excel.application
$xl.displayAlerts = $false # don't prompt the user
$wb1 = $xl.workbooks.open($file1, $null, $true) # open source, readonly
$wb2 = $xl.workbooks.open($file2, $null, $true)
$wb3 = $xl.workbooks.open($destfile) # open target
$sh1_wb2 = $wb2.sheets.item(1) # first sheet in destination workbook
$sheetToCopy = $wb1.sheets.item('Sheet1') # source sheet to copy
$sheetToCopy.copy($sh1_wb2) # copy source sheet to destination workbook
$wb1.close($false) # close source workbook w/o saving
$wb2.close($true) # close and save destination workbook
$xl.quit()
spps -n excel
You can try to use https://github.com/dfinke/ImportExcel
Export data to csv from multiple worksheets with Import-CSV, then combine those CSV files (i suppose that they have identical rows) and import combined CVS back to excel using Export-CSV... quite simple. and does not require any COM manipulations.

Copy multiple Excel worksheets from multiple workbooks to a new workbook using PowerShell

I have been at this for a while and can't seem to find anything that does exactly what I want. I was working off this post: How to use PowerShell to copy several Excel worksheets and make a new one but it doesn't do exactly what I am looking for. I am attempting to copy all worksheets from multiple workbooks and place them in a new workbook. Ideally, I would like to get the file name from one of the workbooks and use it to name the new file in a new directory.
I have found numerous examples of code that can do this, but there are a couple of key features that I am missing and not sure how to implement them. Here is an example of what I have working now:
$file1 = 'C:\Users\Desktop\TestFolder\PredictedAttritionReport.xlsx' # source's fullpath
$file2 = 'C:\Users\Desktop\TestFolder\AdvisorReport' # destination's fullpath
$xl = new-object -c excel.application
$xl.displayAlerts = $false # don't prompt the user
$wb2 = $xl.workbooks.open($file1, $null, $true) # open source, readonly
$wb1 = $xl.workbooks.open($file2) # open target
$sh1_wb1 = $wb1.sheets.item('Report') # second sheet in destination workbook
$sheetToCopy = $wb2.sheets.item('Report') # source sheet to copy
$sh1_wb1.Name = "DeleteMe$(get-date -Format hhmmss)" #Extremely unlikely to be a duplicate name
$sheetToCopy.copy($sh1_wb1) # copy source sheet to destination workbook
$sh1_wb1.Delete()
$wb2.close($false) # close source workbook w/o saving
$wb1.close($true) # close and save destination workbook
$xl.quit()
spps -n excel
The problem that I have is that I need this to work, such that I don't have to input the actual file name since those names may be different each time they are created and there may be 3 or 4 files with more than one worksheet, where this example works off of only two named files. Additionally, I would like to be able to copy all worksheets in a file instead of just a single named worksheet, which in this case is 'Report'. The final piece is saving it as a new Excel file rather than overwriting the existing destination file, but I think I can figure that part out.
You could specify parameters when you call the script, and use the specified values in place of the sheet/file names as required. Read about PowerShell Parameters here. Reply if you need more info on how to implement.
This function will copy over sheets from one excel workbook to other.
You can call with Copy-AllExcelSheet command one, it is loaded into memory.
See below in example:
Function Copy-AllExcelSheet()
{
param($TargetXls, $sourceXls)
$xl = new-object -c excel.application
$xl.displayAlerts = $false
$sourceWb = $xl.Workbooks.Open($sourceXls,$true,$false)
$targetWB = $xl.Workbooks.Open($TargetXls)
foreach($nextSheet in $sourceWb.Sheets)
{
$nextSheet.Copy($targetWB.Sheets[1])
}
$sourceWb.close($false)
$targetWB.close($true)
$xl.Quit()
}
#To call the function
Copy-AllExcelSheet "c:\Targetfile.xlsx" "c:\sourceFile.xlsx"

Why can't I create this chart in excel (using powershell)

Trying to add a chart in excel using powershell. I used the following link for guidance:
http://theolddogscriptingblog.wordpress.com/2010/07/03/how-do-i-change-the-size-or-position-of-my-chart-with-powershell/
Here is the code:
# <---- Start Code --------------------------------------->
$xl = New-Object -comobject Excel.Application
# Show Excel
$xl.visible = $true
$xl.DisplayAlerts = $False
# Open a workbook
$wb = $xl.workbooks.add()
#Create Worksheets
$ws = $wb.Worksheets.Item(1) # Opens Excel and 3 empty Worksheets
1..8 | % { $ws.Cells.Item(1,$_) = $_ } # adds some data
1..8 | % { $ws.Cells.Item(2,$_) = 9-$_ } # adds some data
$range = $ws.range("a${xrow}:h$yrow") # sets the Data range we want to chart
# create and assign the chart to a variable
#$ch = $xl.charts.add() # This will open a new sheet
$ch = $ws.shapes.addChart().chart # This will put the Chart in the selected WorkSheet
$ch.chartType = 58
$ch.setSourceData($range)
$RngToCover = $ws.Range("D5:J19") # This is where we want the chart
$ChtOb = $ch.Parent # This selects the current Chart
$ChtOb.Top = $RngToCover.Top # This moves it up to row 5
$ChtOb.Left = $RngToCover.Left # and to column D
$ChtOb.Height = $RngToCover.Height # resize This sets the height of your chart to Rows 5 - 19
$ChtOb.Width = $RngToCover.Width # resize This sets the width to Columns D - J
<------------- End Code -------------------------------------->
This works on one machine I have which uses Excel 2010, but on another machine using Excel 2003 it fails with the following message:
"Method invocation failed because [System.__ComObject] doesn't contain a method named 'addchart'."
Is this a limitation of the version of Excel I'm using? Using powershell, how can I add a chart within a worksheet in Excel 2003?
According to the documentation the method was added with Excel 2007, so it's not available in Excel 2003. Try recording chart creation as a macro in Excel 2003 and translate the result into PowerShell. You'll probably get something like this:
$chart = $xl.Charts.Add
$chart.ChartType = ...
$chart.SetSourceData $xl.Sheets(1).Range(...), ...
$chart.Location ...

Resources