Powershell: Placing Second X-Axis on bar chart - powershell

The following chart using powershell and csv file.
I would also like to add the 'Time' as the top secondary X-Axis, but I do not know how to add it to the series.
I suspect it's the line with $chart1.Series["Elapse"].Points.DataBindXY($date, $totalMinutes)
$chart1.Series["Elapse"].Points.DataBindXY($date, $totalMinutes), but how is DataBind XY determined with two X-Axis?
CVS:
Date,Time,Attempts,TotalMinutes
06/08/2020,20:48,6,6.08613289666667
06/08/2020,21:20,9,9.10416342666667
06/09/2020,07:25,2,2.06852810833333
powershell:
#CONSTANTS
$directory = "C:\Users\gamble.pw\Desktop\powershell"
$csvFile = "logfile.csv"
#chart object
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
$chart1 = New-object System.Windows.Forms.DataVisualization.Charting.Chart
$chart1.Width = 2000
$chart1.Height = 1000
$chart1.BackColor = [System.Drawing.Color]::White
#title
[void]$chart1.Titles.Add("Login Time")
$chart1.Titles[0].Font = "segoeuilight,20pt"
$chart1.Titles[0].Alignment = "topLeft"
#chart area
$chartarea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
$chartarea.Name = "ChartArea1"
$chartarea.AxisY.Title = "Elapse Time in Minutes"
$chartarea.AxisX.Title = "Date"
$chartarea.AxisX2.Title = "Time"
$chartarea.AxisY.Interval = 1
$chartarea.AxisX.Interval = 1
$chart1.ChartAreas.Add($chartarea)
#data source
$datasource = Import-Csv "$directory\$csvFile"
$date = $datasource.Date
$time = $datasource.Time
$totalMinutes = $datasource.TotalMinutes
Write-Host $date
Write-Host $time
Write-Host $attempts
Write-Host $totalMinutes
#data series
[void]$chart1.Series.Add("Elapse")
#$chart1.Series["Elapse"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line
$chart1.Series["Elapse"].BorderWidth = 2
$chart1.Series["Elapse"].Points.DataBindXY($date, $totalMinutes)
$chart1.SaveImage("$directory\Bar_Chart_Login.png","png")

You should have a different series for each axis. You have to define in the Series which axes to use. Once you know which axis you want the Series to go with, you can set it's AxistType.
$chart1.Series["Elapse"].YAxisType = AxisType.Secondary;
$chart1.Series["Elapse"].XAxisType = AxisType.Secondary;
Once you have your AxisType set, when you databind the Series it will know which axis to display it on.

Related

Powershell cannot Get data from Generated Textbox

Making a small Budgeting app that populates bills from a list (in my Settings tab, this works fine).
Depending what you have for bills, it will generate what you see in screenshot (1 Label, 2 Textboxes, Calendar, and a Checkbox)
My Issue,
I can not seem to get data from any of these generated components. The goal is for all the Payment Due textboxes to add up their Sum to have a total. Here is what the generated function looks like.
function Generate-Bills
{
$Due = #() # <- Array for Due Bills
$coord = 40
foreach ($bill in Get-Content "$path\House.txt") #<- list of bills stored in this text file
{
$BillName = $bill
$BillDue = $bill + "Due"
$BillNext = $bill + "Next"
$BillDate = $bill + "Date"
$BillCheck = $bill + "Check"
Write-Host $BillName
Write-Host $BillDue
Write-Host $BillNext
Write-Host $BillDate
Write-Host $BillCheck
Write-Host $coord
$BillCheck = New-Object 'System.Windows.Forms.CheckBox'
$BillDate = New-Object 'System.Windows.Forms.DateTimePicker'
$BillNext = New-Object 'System.Windows.Forms.TextBox'
$BillDue = New-Object 'System.Windows.Forms.TextBox'
$BillName = New-Object 'System.Windows.Forms.Label'
#
# Checkbox
#
$BillCheck.Left = '478'
$BillCheck.Top = $coord
$BillCheck.Name = $BillCheck
$BillCheck.Size = '104, 24'
$BillCheck.TabIndex = 4
$BillCheck.Text = 'Paid'
$BillCheck.ForeColor = $textcolor
$BillCheck.UseCompatibleTextRendering = $True
$BillCheck.UseVisualStyleBackColor = $True
$BillCheck.Anchor = 'Top'
#
# Due Date
#
$BillDate.Left = '360'
$BillDate.Top = $coord
$BillDate.Name = $BillDate
$BillDate.Size = '110, 20'
$BillDate.TabIndex = 3
$BillDate.Format = 'Short'
$BillDate.Font = 'Microsoft Sans Serif, 12pt '
$BillDate.Anchor = 'Top, Bottom'
#
# Next Payment
#
$BillNext.Left = '238'
$BillNext.Top = $coord
$BillNext.Name = $BillNext
$BillNext.Size = '100, 20'
$BillNext.TabIndex = 2
$BillNext.Backcolor = '33, 35, 50'
$BillNext.BorderStyle = 'None'
$BillNext.ForeColor = 'White'
$BillNext.Font = 'Microsoft Sans Serif, 18pt, style=Bold'
$BillNext.Anchor = 'Top, Bottom'
#
# Due Payment
#
$BillDue.Left = '108'
$BillDue.Top = $coord
$BillDue.Name = $BillDue
$BillDue.Size = '100, 20'
$BillDue.TabIndex = 1
$BillDue.Backcolor = '33, 35, 50'
$BillDue.BorderStyle = 'None'
$BillDue.ForeColor = 'White'
$BillDue.Font = 'Microsoft Sans Serif, 18pt, style=Bold'
$BillDue.Anchor = 'Top, Bottom'
#Fail Attempt :(
$BillDue.Add_TextChanged({Write-Host $BillDue.Text})
#
# Name of Bill
#
$BillName.AutoSize = $True
$BillName.Left = '18'
$BillName.Top = $coord
$BillName.Name = $BillName
$BillName.Size = '35, 17'
$BillName.TabIndex = 0
$BillName.Text = $bill
$BillName.Font = 'Microsoft Sans Serif, 10pt, style=Bold'
$BillName.ForeColor = 'White'
$BillName.UseCompatibleTextRendering = $True
$BillName.Anchor = 'Top, Bottom'
#
# Controls
#
$HouseGenPanel.Controls.Add($BillCheck)
$HouseGenPanel.Controls.Add($BillDate)
$HouseGenPanel.Controls.Add($BillNext)
$HouseGenPanel.Controls.Add($BillDue)
$HouseGenPanel.Controls.Add($BillName)
$data += $BillDue.Text
$coord += 50
$HouseGenPanel.Height += 45
}
Write-Host $Due "data"
}
I have tried getting it to store the textbox data into an array, but it will not let me pull it,
I have also tried making it so when the textbox updates, it reports the new numbers, but I cant seem to find a way for it to update each textbox properly.
Any Guidance on this is much appreciated as this is the only thing stopping me from finishing this app. (source code will be released on completion.)
== Solution ===
$global:controls = $HousePanel.controls
$output.Text = $global:controls['TextBox1'].text
$global:controls['TextBox1'].Add_TextChanged({ $output.Text = $global:controls['TextBox1'].text})
Add controls to a global variable, then call the generated .Name
By throwing the controls into a global variable, I was able to access generated variables, and get their updated text with the following snippet.
$global:controls = $HousePanel.controls
$output.Text = $global:controls['TextBox1'].text
$global:controls['TextBox1'].Add_TextChanged({ $output.Text = $global:controls['TextBox1'].text})

Use Powershell to split one column of an excel workbook by a delimiter

Hello all I am still trying to learn power shell. the issue I have is that I am trying to use Power shell to look at one column in a workbook and split it into several columns by a delimiter (=) horizontally 3 times. I have also looked into using the split option but I do not understand exactly how to do either. I can not post the either sheet but the line is
Hash_tag
This is what I would like to see
The below is that I have
$SRReport="C:\Users\ddpierce\Desktop\Metrics\u_service_request.csv"
$OBJExcel=New-Object -ComObject Excel.Application
$OBJexcel.visible=$true
$WorkBook=$objExcel.Workbooks.Open($SRReport)
$worksheets=$workbook.worksheets
$sheet=$worksheets.item(1)
$sheet.activate
$range=$sheet.usedrange
$a = $countrange
$colA=$sheet.range("A1").EntireColumn
$colrange=$sheet.range("A1")
$xlDelimited = 1
$xlTextQualifier = -4142
$xlTextFormat = 1
$xlConsecutiveDelimiter = $true
$xlTab = $flase
$xlSemicolon = $true
$xlComma = $true
$xlSpace = $true
$xlOther = $flase
$xlOtherChar = $true,':'
#Convert Text To Columns
#$colA.texttocolumns($colrange,$xlDelimited,$xlTextQualifier,$true,$false,$false,$false,$false)# = nothing 1
#$colA.texttocolumns($colrange,$xlDelimited,$xlTextQualifier,$false,$true,$false,$false,$false)# = nothing 2
#$colA.texttocolumns($colrange,$xlDelimited,$xlTextQualifier,$false,$false,$true,$false,$false)# = split on simi 3
#$colA.texttocolumns($colrange,$xlDelimited,$xlTextQualifier,$false,$false,$false,$true,$false)# = split on comma 4
#$colA.texttocolumns($colrange,$xlDelimited,$xlTextQualifier,$false,$false,$false,$false,$true)# = split on space 5
#$colA.texttocolumns($colrange,$xlDelimited,$xlTextQualifier,$true,$true,$true,$true,$true,$true,$true)
$colA.texttocolumns($colrange,$xlDelimited,$xlTextQualifier,$xlConsecutiveDelimiter,$xlTab,$xlSemicolon,$xlComma,$xlSpace,$xlOther,$xlOtherChar)
#$sheet.columns.autofit()
#Save as XLSX
#$workbook.saveas("C:\Users\ddpierce\Desktop\Metrics\u_service_request2.csv")
#$WorkBook.save=$true
#$workbook.close($true)
#$objExcel.Quit()

Calculate two audio duration with frame

I am stuck, I need a small logic.
I have two audio durations
x = "00:00:07:18"
y = "00:00:06:00" H : M: S: F
Answer should be x + y = 00:00:13:18
H=hours S= seconds M=minutes F=frame
My question is
if x = "00:00:03:14"
y = "00:00:13:18"
answer should be x + y = **00:00:17:02**
If the frame is greater than 30 it should increase 1 in second.
I am using power shell. How can I determine the logic to calculate both of this?
Calculation of the first 3 parts (hour:minute:second), we can offload to the [timespan] type, then all we need to worry about is carrying excess frames over:
# Simple helper function to turn our input strings into a [timespan] + frame count
function Parse-FrameDuration
{
param(
[string]$Duration
)
$hour,$minute,$second,$frame = ($Duration -split ':') -as [int[]]
[PSCustomObject]#{
Time = New-TimeSpan -Hours $hour -Minutes $minute -Seconds $second
Frame = $frame
}
}
# function to do the actual calculation
function Add-Frame
{
param(
[string]$Base,
[string]$Offset
)
# Parse our two timestamps
$a = Parse-FrameDuration $Base
$b = Parse-FrameDuration $Offset
# Calculate frames % frame rate, remember to carry any excess seconds
$frames = 0
$carry = [math]::DivRem($a.Frame + $b.Frame , 30, [ref]$frames)
# Calculate time difference, add any extra second carried from frame count
$new = ($a.Time + $b.Time).Add($(New-TimeSpan -Seconds $carry))
# Stitch output string together from new timespan + remaining frames
return "{0:hh\:mm\:ss}:{1:00}" -f $new,$frames
}
Now we can do:
PS C:\> Add-Frame -Base 00:00:03:14 -Offset 00:00:13:18
00:00:17:02

Odd and even pages footer - page X of Y in powershell

I would like to generate word documents in Powershell with different footer on even and odd pages.
I would like to have text with data on left side, and Page X of Y on right side on one page and reverse combination on next page.
First problem is in X of Y format. And second problem I have with placing text with field in one footer. If I put field, the text was disappear, and when I put text, field was disappearing.
PowerShell add field codes to ms word footer - does not work in my case.
I will be grateful for your help.
$dat = Get-Date -Format yyyy-MM-dd
$word = New-Object -ComObject word.application
$word.Visible = $false
$doc = $word.documents.add()
$doc.PageSetup.OddAndEvenPagesHeaderFooter = $true
$selection = $word.Selection
# ...
# content
# ...
$section = $doc.sections.item(1)
$footer = $section.Footers(1)
$Range = $footer.Range
$Range.Text = "Some text($dat)"
$Range.ParagraphFormat.Alignment = 0
$footer.PageNumbers.Add(2)
$Range.Font.Size = 10
$footer = $section.Footers(3)
$Range = $footer.Range
$Range.Text = "Some text($dat)"
$Range.ParagraphFormat.Alignment = 2
$footer.PageNumbers.Add(0)
$Range.Font.Size = 10
$outputPath = 'C:\FileToDocx.docx'
$doc.SaveAs($outputPath)
$doc.Close()
$word.Quit()
The problem is also that the $footer.PageNumbers.Add() is global and it does not depend from my odd and even footer range.
Also I was tried resolve my problem by swap PageNumbers to combination of $Range.Fields.Add($Range, 26) and $Range.Fields.Add($Range, 33), e.g.
$fieldsPage = $Range.Fields.Add($Range, 33)
$sumField = $fieldsPage.Result.Text
$fieldsNumPages = $Range.Fields.Add($Range, 26)
$sumField += ' of ' + $fieldsNumPages.Result.Text
$range.Text = "Some text($dat)`t`tPage $sumField"
but in this case I have static string. I don't know how to use this two type of fields with static text with $dat in footer without conversion to string. The footer forces me to use fields, because only they can be different on each page.

PowerShell accessing data from hashtable inside hashtable

I have 5 hash tables:
$Monday = #{RUG = "";NRH1 = "";NRH2 = "";ELM = "";BAGVAGT = ""}
$Tuesday = #{RUG = "";NRH1 = "";NRH2 = "";ELM = "";BAGVAGT = ""}
$Wednesday = #{NRH1 = "";NRH2 = "";ELM = "";BAGVAGT = ""}
$Thursday = #{NRH1 = "";NRH2 = "";ELM = "";BAGVAGT = ""}
$Friday = #{NRH1 = "";NRH2 = "";ELM = ""}
That get filled with data. And I can get data out from these either one at at time with $Monday.RUG or all with $Monday | out-string. No problem there.
I'm going to combine those in another hash table 100 times with different data.
So it will be like this:
$Week = #{
1 = #{mo=$Monday;tu=$Tuesday;we=$Wednesday;th=$Thursday;fr=$Friday;val=$value}
2 = #{mo=$Monday;tu=$Tuesday;we=$Wednesday;th=$Thursday;fr=$Friday;val=$value}
}
And so on, until I have 100 different weeks with different values (value will be a calculated number)
But the question is. How do I access the items in the hashtables inside the $week hashtable?
Is there a direct way like $week.1.mo ? or do you need to use a loop?
You can access it using:
$Week[1].mo