Odd and even pages footer - page X of Y in powershell - 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.

Related

How to add fields in table to a Word document with Powershell

I'm able to add fields in the footer of a word document, like this :
$footer = $Section.Footers.Item(1)
$footer.Range.Text = "";
$Footer.Range.ParagraphFormat.Alignment=2
$Range = $Footer.Range
$null = $ExistingDoc.Fields.Add($footer.range, 33) # Page
$Range.SetRange($Range.end + 1,$Range.end + 1)
$null = $Range.InsertBefore(' of ')
$Range.SetRange($Range.end + 1,$Range.end + 1)
$null = $ExistingDoc.Fields.Add($range, 26) # Total Page
$Range.SetRange($Range.star,$Range.start)
$null = $Range.InsertBefore('Page ')
$Footer.Range.ParagraphFormat.Alignment=2
But I'm not able to add a table and put fields in it.
I tried many syntaxes with no luck like :
$table2 = $ExistingDoc.Tables.Add($footer.range,2,3)
$range2 = $table2.cell(1,1).select
$null = $ExistingDoc.Fields.Add($Footer.range.Tables(2), 33)
or
$table2 = $ExistingDoc.Tables.Add($footer.range,2,3)
$null = $ExistingDoc.Fields.Add($table2.cell(1,1), 33)
I did it with a macro and find the following code :
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
"PAGE ", PreserveFormatting:=True
But no luck to convert it to Powershell, any help is welcome.

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()

Powershell: Placing Second X-Axis on bar chart

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.

Check inputs for bad characters, NaN, length

I am searching for a general input check and I already found some things like NaN or if it is to short but how can you check if there are characters like ($§?=) which you do not want in your input to be?
My second question is what is important to check if you wanna rename a file using an input. Except length.
EDIT:
if($ParID -lt 6) {
$specific_error = "Par ID is is too short!"
} else { #else 1
if(!($ParID -match "[1-999999]")) {
$specific_error = "Par ID must only contain numbers!"
} else { #else 2
}#else 2
} #else 1
EDIT 2:
$ParIDInbox = New-Object System.Windows.Forms.TextBox #initialization -> initializes the input box
$ParIDInbox.Location = New-Object System.Drawing.Size(10,30) #Location -> where the label is located in the window
$ParIDInbox.Size = New-Object System.Drawing.Size(260,20) #Size -> defines the size of the inputbox
$ParIDInbox.MaxLength = 6 #sets max. length of the input box to 6
To check whether the filename contains any unwanted character you can use a regex:
$invalidCharacter = '$§?='
[regex]$invalidCharacter = '[{0}]' -f ([regex]::Escape($invalidCharacter))
if ($invalidCharacter.IsMatch($yourFileName))
{
# filename contains some invalid character ...
}
To ensure the filename is valid, you could use the GetInvalidFileNameChars .NET method to retrieve all invalid character and again use a regex to check whether the filename is valid:
[regex]$containsInvalidCharacter = '[{0}]' -f ([regex]::Escape([System.IO.Path]::GetInvalidFileNameChars()))
$yourFileName = 'invali?idFilename.txt'
if ($containsInvalidCharacter.IsMatch($yourFileName))
{
# filename is invalid...
}