Freeze Column Headers in excel after export from ssrs - reporting-services

I have created a report and now I need to freeze tablix header. I tried all the ways related to freeze panes in SSRS, but after export to excel, the freeze pane is not working. Do you know any way to achieve this in SSRS 2016?
Below are the steps that I've tried:
Select the tabix and click on Tablix properties.
In the General tab under Column Headers section you can see "Keep header visible while scrolling" checkbox, check it.
Now the header row will be remain fixed in the report.
OR
In the grouping pane, make sure to turn on advanced mode (click on the small black down arrow on the far right of the grouping pane)
Select the corresponding (Static) item in the row group hierarchy
In the properties grid, set RepeatOnNewPage to true
KeepwithGroup to After
OR
Freeze the header of all columns[ Freezing table header ] : To do select static member of table header row from row groups [ Advanced
Mode ] and set FixedData to true
Freeze the initial 2 columns : To do select static member of columns in column group and set fixedData to true.

There are a two different solutions that I know of to this problem. Each has its pros and cons.
Solution 1
You can follow this guide on mssqltips.com. This solution has you create a text box for each column and place it in the report header. It is a tedious and cumbersome way to get the job done but it works and it is all contained within the report.
Solution 2
The second way to accomplish this is with powershell. This solution only works if you can schedule the distribution of the report instead of having on demand access in the SSRS portal. You have powershell generate the report, modify the output, and distribute. Below is a sample powershell script.
#Set variables
$ReportServerUri = "http://MySsrsServer/ReportServer_MySsrsServer/ReportExecution2005.asmx?WSDL"
$ReportPath = "/MyReportPath"
$ReportOutputType = "EXCEL"
$ReportOutputDirectory = "C:\SsrsOutput\"
$ReportOutputFileName = "MyReport.xlsx"
$ReportOutput = $ReportOutputDirectory + $ReportOutputFileName
#Connect to web service
$ReportServer = New-WebServiceProxy -Class 'ReportServer' -Namespace 'ReportServer' -Uri $ReportServerUri -UseDefaultCredential
$ReportServer.Url = $ReportServerUri
#Load report
$Report = $ReportServer.GetType().GetMethod("LoadReport").Invoke($ReportServer, #($ReportPath, $null))
#Other variables to hold parameters and output values
$parameters = #()
$deviceInfo = "<DeviceInfo><NoHeader>True</NoHeader></DeviceInfo>"
$extension = ""
$mimeType = ""
$encoding = ""
$warnings = $null
$streamIDs = $null
#Render the report
$RenderOutput = $ReportServer.Render($ReportOutputType,
$deviceInfo,
[ref] $extension,
[ref] $mimeType,
[ref] $encoding,
[ref] $warnings,
[ref] $streamIDs
)
#Write file
$Stream = New-Object System.IO.FileStream($ReportOutput), Create, Write
$Stream.Write($RenderOutput, 0, $RenderOutput.Length)
$Stream.Close()
#Open Excel
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false
$excel.DisplayAlerts = $False
#Open File
$workbook = $excel.Workbooks.Open($ReportOutput)
#Disable Split
$excel.ActiveWindow.Split = $false
#Freeze Panes
$excel.Rows.Item("10:10").Select() | Out-Null
$excel.ActiveWindow.FreezePanes = $true
#Save and Close Workbook
$xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault
$workbook.SaveAs($ReportOutput, $xlFixedFormat)
$workbook.Close($true)
#Close Excel
$excel.Quit()
#Send out email
Send-MailMessage -From "MySsrsReports#MyOrg.com" -To "ReportUsers#MyOrg.com" -Subject "My Report" -SmtpServer "email.myorg.com" -Attachments $ReportOutput

Related

What is the ItemType for SSRS Catalog Type 14?

SQL Server 2019. I manually uploaded a xlsx file to the server and it was placed in an "Excel Workbooks" group. When I look in the reportserver catalog table I see the Type value is 14. I'm trying to write a powershell script to upload a bunch of xlsx files instead of having to do it manually, one by one. I need to know the ItemType. I can use "Resource" but it doesn't upload it to the "Excel Workbooks" group, it uploads it to the "Resources" group. I did list everything in my report server and see the TypeName for the xlsx I manually uploaded is "ExcelWorkbook", but is not a valid ItemType. Any suggestions? Below is the powershell I'm using (I'm still new to powershell). Thanks!
$WebServiceUrl = "http://xxxx"
$ReportFolder = "PDF_Reports2"
$SourceDirectory = $PSScriptRoot
$Overwrite = $true
$SSRSProxy = New-WebServiceProxy -Uri $WebServiceUrl'/ReportServer/ReportService2010.asmx?WSDL' -UseDefaultCredential
# LIST ITEMS IN SERVER
#$SSRSProxy.ListChildren("/",$true)
$type = $SSRSProxy.GetType().Namespace
$datatype = ($type + '.Property')
$Property =New-Object ($datatype);
$Property.Name = "MimeType"
$Property.Value = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
$SourceDirectory = "c:\tmp\SSRS\"
$ItemType = "Resource" # Resource works, but it gets put in the Resources group, I want it in the Excel Workbooks group.
$ReportFolder = "/PDF_Reports2"
ForEach ($rdlfile in Get-ChildItem $SourceDirectory -Filter "*.xlsx" | Where-Object { $_.Attributes -ne "Directory" } )
{
$byteArray = [System.IO.File]::ReadAllBytes($rdlfile.FullName)
write-host $rdlfile.FullName
$Warnings = #();
$SSRSProxy.CreateCatalogItem($ItemType, $rdlfile, $ReportFolder, $Overwrite, $byteArray, $Property, [ref]$Warnings)
$warnings.Length
}

How do I dynamically insert a string into a text file in PowerShell?

The text is an html file. The line I am interested in looks something like:
<td>INC1234</td><td>INC1235</td><td>INC1236</td>
The INC numbers are different from file to file. I'd like to parse through the line by saying something like:
if like <td>INC, then concatenate '<td><a href="https://www.website.com/=' + INC# + '>"
To give an output like:
<td><a href="https://www.website.com/=INC1234>INC1234</a></td><td><a href="https://www.website.com/=INC1235>INC1235</a></td><td><a href="https://www.website.com/=INC1236>INC1236</a></td>"
EDIT1: Ok, if I do something like:
$parse = (-split (Get-Content -Raw C:\Temp\report.txt) -match '<td>INC')
$parse
It will find the characters, but it will return the entire line rather than looking for more that match the 'INC'. Presumably because they all reside on the same line with no spaces.
EDIT2: Maybe this will help. What I'm doing is using PowerShell to write SQL commands, send it to our SQL Server, return the data and use PSWriteHTML to build the report which works fantastic. But I am wanting the first column, which is the ticket number (eg. INC1234) to be a link to the ticket it reads.
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True)]
[string]$ReportName
)
## Build the query box
function Read-MultiLineInputBoxDialog([string]$Message, [string]$WindowTitle, [string]$DefaultText)
{
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms
## Create the Label.
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Size(10,10)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.AutoSize = $true
$label.Text = $Message
## Create the TextBox used to capture the user's text.
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Size(10,40)
$textBox.Size = New-Object System.Drawing.Size(575,200)
$textBox.AcceptsReturn = $true
$textBox.AcceptsTab = $false
$textBox.Multiline = $true
$textBox.ScrollBars = 'Both'
$textBox.Text = $DefaultText
## Create the OK button.
$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Size(415,250)
$okButton.Size = New-Object System.Drawing.Size(75,25)
$okButton.Text = "OK"
$okButton.Add_Click({ $form.Tag = $textBox.Text; $form.Close() })
## Create the Cancel button.
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Size(510,250)
$cancelButton.Size = New-Object System.Drawing.Size(75,25)
$cancelButton.Text = "Cancel"
$cancelButton.Add_Click({ $form.Tag = $null; $form.Close() })
## Create the form.
$form = New-Object System.Windows.Forms.Form
$form.Text = $WindowTitle
$form.Size = New-Object System.Drawing.Size(610,320)
$form.FormBorderStyle = 'FixedSingle'
$form.StartPosition = "CenterScreen"
$form.AutoSizeMode = 'GrowAndShrink'
$form.Topmost = $True
$form.AcceptButton = $okButton
$form.CancelButton = $cancelButton
$form.ShowInTaskbar = $true
## Add all of the controls to the form.
$form.Controls.Add($label)
$form.Controls.Add($textBox)
$form.Controls.Add($okButton)
$form.Controls.Add($cancelButton)
## Initialize and show the form.
$form.Add_Shown({$form.Activate()})
$form.ShowDialog() > $null # Trash the text of the button that was clicked.
## Return the text that the user entered.
return $form.Tag
}
## Prompt the SQL Query Box
$Query = Read-MultiLineInputBoxDialog -Message "Enter SQL Query Here" -WindowTitle "SQL Query" -DefaultText "SELECT FROM"
if ($Query -eq $null) { Break }
else { Write-Host "You entered the following text: $Query" }
## Pass query to SQL Server
$Pass = Invoke-Sqlcmd -Query $Query -ServerInstance "MY-SERVER-INSTANCE" -Username "USERNAME" -Password "PASSWORD"
## Output the report and save to the network under the specified name
New-HTML {
New-HTMLTable -EnableColumnReorder -DisableInfo -DataTable $Pass -ExcludeProperty "RowError", "RowState", "Table", `
"ItemArray", "HasErrors" -HideFooter -PagingLength 25 -SearchBuilder
New-HTMLTableStyle -FontFamily Calibri -FontSize 15 -FontStyle normal -TextAlign center -TextColor "#0a0a0a"
New-HTMLTableStyle -FontFamily Calibri -BackgroundColor "#fffdb5" -FontSize 15px -TextColor "#0a0a0a" -TextAlign center -Type RowHover
} -ShowHTML -FilePath "\\Server\$ReportName.html" -Online
The report looks something like:
Ticket: Description:
----------------------------
INC1234 Broken Monitor
INC1235 No Sound
The HTML that PSWriteHTML builds throws all of the ticket numbers on one line so I would like to edit that HTML with the <a href=""> tag to dynamically create links for each ticket # mainly because I don't know how to do it in PS and can't seem to find a good answer through Google - which is why I came here.
Although not familiar with PsWriteHtml, I guess you could simply change the Ticket properties in the array you receive in $Pass:
## Pass query to SQL Server
$Pass = Invoke-Sqlcmd -Query $Query -ServerInstance "MY-SERVER-INSTANCE" -Username "USERNAME" -Password "PASSWORD"
# convert all Tickets into hyperlinks
foreach ($item in $Pass) {
$item.Ticket = '<a href="https://www.website.com/={0}>{0}</a>'-f $item.Ticket
}
Then the rest of your code
## Output the report and save to the network under the specified name
New-HTML {...}

Function not found on first attempt

I have a script, which creates a GUI to put in parameters to create an AD user. The script contains a large function (one that creates a AD browser that I found on the net). The function is called right at the start of the script (one textbox requires input from the function to prefill a value) or by clicking a button in the GUI. Problem is, that when I run the script, I get error message saying, that "The term 'Browse-AD' (=name of the function) is not recognised as the name of a cmdlet, function..." When I run it from PowerShell ISE, I get this error for the first time I try, the script launches (but the browser doesn't work) and after cancelling the script and running it again the browser works fine, no error message is displayed. I didn't touch the script in the mean time, I just run it for the second time, no changes made. But the bigger problem is, that when the script is launched from a file directly (which is naturally its intended way of usage), it's always the first attempt and therefore the error is always displayed and browser doesn't work. Any idea what's happening?
This is the function:
function Browse-AD()
{
# original inspiration: https://itmicah.wordpress.com/2013/10/29/active-directory-ou-picker-in-powershell/
# author: Rene Horn the.rhorn#gmail.com
<#
Copyright (c) 2015, Rene Horn
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
$dc_hash = #{}
$selected_ou = $null
Import-Module ActiveDirectory
$forest = Get-ADForest
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
function Get-NodeInfo($sender, $dn_textbox)
{
$selected_node = $sender.Node
$dn_textbox.Text = $selected_node.Name
}
function Add-ChildNodes($sender)
{
$expanded_node = $sender.Node
if ($expanded_node.Name -eq "root") {
return
}
$expanded_node.Nodes.Clear() | Out-Null
$dc_hostname = $dc_hash[$($expanded_node.Name -replace '(OU=[^,]+,)*((DC=\w+,?)+)','$2')]
$child_OUs = Get-ADObject -Server $dc_hostname -Filter 'ObjectClass -eq "organizationalUnit" -or ObjectClass -eq "container"' -SearchScope OneLevel -SearchBase $expanded_node.Name
if($child_OUs -eq $null) {
$sender.Cancel = $true
} else {
foreach($ou in $child_OUs) {
$ou_node = New-Object Windows.Forms.TreeNode
$ou_node.Text = $ou.Name
$ou_node.Name = $ou.DistinguishedName
$ou_node.Nodes.Add('') | Out-Null
$expanded_node.Nodes.Add($ou_node) | Out-Null
}
}
}
function Add-ForestNodes($forest, [ref]$dc_hash)
{
$ad_root_node = New-Object Windows.Forms.TreeNode
$ad_root_node.Text = $forest.RootDomain
$ad_root_node.Name = "root"
$ad_root_node.Expand()
$i = 1
foreach ($ad_domain in $forest.Domains) {
Write-Progress -Activity "Querying AD forest for domains and hostnames..." -Status $ad_domain -PercentComplete ($i++ / $forest.Domains.Count * 100)
$dc = Get-ADDomainController -Server $ad_domain
$dn = $dc.DefaultPartition
$dc_hash.Value.Add($dn, $dc.Hostname)
$dc_node = New-Object Windows.Forms.TreeNode
$dc_node.Name = $dn
$dc_node.Text = $dc.Domain
$dc_node.Nodes.Add("") | Out-Null
$ad_root_node.Nodes.Add($dc_node) | Out-Null
}
return $ad_root_node
}
$main_dlg_box = New-Object System.Windows.Forms.Form
$main_dlg_box.ClientSize = New-Object System.Drawing.Size(400,600)
$main_dlg_box.MaximizeBox = $false
$main_dlg_box.MinimizeBox = $false
$main_dlg_box.FormBorderStyle = 'FixedSingle'
# widget size and location variables
$ctrl_width_col = $main_dlg_box.ClientSize.Width/20
$ctrl_height_row = $main_dlg_box.ClientSize.Height/15
$max_ctrl_width = $main_dlg_box.ClientSize.Width - $ctrl_width_col*2
$max_ctrl_height = $main_dlg_box.ClientSize.Height - $ctrl_height_row
$right_edge_x = $max_ctrl_width
$left_edge_x = $ctrl_width_col
$bottom_edge_y = $max_ctrl_height
$top_edge_y = $ctrl_height_row
# setup text box showing the distinguished name of the currently selected node
$dn_text_box = New-Object System.Windows.Forms.TextBox
# can not set the height for a single line text box, that's controlled by the font being used
$dn_text_box.Width = (14 * $ctrl_width_col)
$dn_text_box.Location = New-Object System.Drawing.Point($left_edge_x, ($bottom_edge_y - $dn_text_box.Height))
$main_dlg_box.Controls.Add($dn_text_box)
# /text box for dN
# setup Ok button
$ok_button = New-Object System.Windows.Forms.Button
$ok_button.Size = New-Object System.Drawing.Size(($ctrl_width_col * 2), $dn_text_box.Height)
$ok_button.Location = New-Object System.Drawing.Point(($right_edge_x - $ok_button.Width), ($bottom_edge_y - $ok_button.Height))
$ok_button.Text = "Ok"
$ok_button.DialogResult = 'OK'
$main_dlg_box.Controls.Add($ok_button)
# /Ok button
# setup tree selector showing the domains
$ad_tree_view = New-Object System.Windows.Forms.TreeView
$ad_tree_view.Size = New-Object System.Drawing.Size($max_ctrl_width, ($max_ctrl_height - $dn_text_box.Height - $ctrl_height_row*1.5))
$ad_tree_view.Location = New-Object System.Drawing.Point($left_edge_x, $top_edge_y)
$ad_tree_view.Nodes.Add($(Add-ForestNodes $forest ([ref]$dc_hash))) | Out-Null
$ad_tree_view.Add_BeforeExpand({Add-ChildNodes $_})
$ad_tree_view.Add_AfterSelect({Get-NodeInfo $_ $dn_text_box})
$main_dlg_box.Controls.Add($ad_tree_view)
# /tree selector
if ($main_dlg_box.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK)
{
return $dn_text_box.Text
}
return $null
}
This is definition of the button that shall launch the browser:
$Select_AD_path = New-Object System.Windows.Forms.Button
$Select_AD_path.Text = "Browse..."
$Select_AD_path.Width = 100
$Select_AD_path.Height = 30
$Select_AD_path.Location = New-Object System.Drawing.Point(90,155)
$Select_AD_path.Font = 'Microsoft Sans Serif,10'
$Select_AD_path.add_Click({
$dn = Browse-AD
if ($dn)
{
$Location_val.Text = $dn
}
})
Also, I put the function to the value of a textbox, so that the browser launches before the script itself runs and prefills the AD path directly to the value I need it:
$Location_val = New-Object system.Windows.Forms.TextBox
$Location_val.multiline = $false
$Location_val.text = Browse-AD
$Location_val.width = 250
$Location_val.height = 20
$Location_val.location = New-Object System.Drawing.Point(200,160)
The precise error message is this:
Browse-AD : The term 'Browse-AD' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Users\a.Petr.Synek\Documents\New_ADuser_woodgroup_complete.ps1:204 char:42
+ $Location_standard_val.Text = Browse-AD
+ ~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Browse-AD:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
At the 204th row there is this text: $Location_val.text = Browse-AD
As requested, my comment as answer:
In your script, you need to put the Browse-AD function on top and all the rest of your code beneath that.
If this order is incorrect, the first time running, the function is called before it has been parsed, giving you the error message.
The second time, PowerShell already parsed the entire code, so then the function is known. PowerShell (unlike VBScript) parses code from top to bottom.

How to add a SQL update statement to powershell after a foreach loop

I'm a noob with PowerShell. and have a question.
I have a working PS1 script that runs a SQL query to get a ID parameter, then creates a PDF from a Crystal Report, form another program based on that returned SQL query and then, loops through the returned parameters and repeats.
What I need is to add an SQL update statement to the PS1 script, that updates a table based on the same ID that is returned from the SQL query, after the PDF is created. Before moving on to the next ID, or after the script creates all the PDF's based on the Id's.
This is what I need to add to the script.
Update DB2.dbo.table2
SET DB2.dbo.table2.Field_01 = 1
FROM DB2.dbo.table2
WHERE (DB2.dbo.Table2.ID = {ID})
The SP1 script that works looks like this.
$serverName="MAIN"
$databaseName="DB1"
$sqlCommand="select ID from ID_Query"
$connectionString = "Data Source=$serverName; " +
"Integrated Security=SSPI; " +
"Initial Catalog=$databaseName"
$connection = new-object system.data.SqlClient.SQLConnection($connectionString)
$command = new-object system.data.sqlclient.sqlcommand($sqlCommand,$connection)
$connection.Open()
$adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
$dataset = New-Object System.Data.DataSet
$adapter.Fill($dataSet) | Out-Null
$connection.Close()
foreach ($Row in $dataSet.Tables[0].Rows)
{
$commandLine= -join(#'
"C:\Program Files (x86)\CR_Program\Program_name\CR_Printer.exe" -report="C:\Crystal_report.rpt" -exportformat=PDF -exportfile="c:\test\{Parameters.ID}.pdf" -parameters"
'#,$($Row[0]),#'
"
'#)
cmd /c $commandLine
}
I hoping to mark a column field_01 to 1, so the script does not create another Crystal repoort.pdf for the same ID, as the ID will be marked to 1 then the query that runs wont see it.
or maybe there a better way to do this.
Thanks.
You can add a timestamp to the filename along with the first field of your DataTable (query results) supposing it's an ID :
# After $connection.Close()
$crPrinter = "C:\Program Files (x86)\CR_Program\Program_name\CR_Printer.exe"
$report = "-report='C:\Crystal_report.rpt'"
foreach ($Row in $dataSet.Tables[0].Rows)
{
$now = [DateTime]::Now.ToString("yyMMddHHmmss")
$outputFile = "-exportfile='c:\test\Report_id_$Row[0]_$now.pdf' -parameters"
$commandLine= [string]::Format("{0} {1} {2}", $crPrinter, $report, $outputFile)
cmd /c $commandLine
Start-Sleep 1 # Sleeps the script to offset a second
}

Global Variables from WinForm

I am currently trying to use the values of a date/time picker variable from one function and use it multiple times in another function. The date/time picker is on a form, so when a user sets a start date and end date, those values are assigned to a variable to use in the other function, which should call both those variables at least twice. While trying to call that variable from the first function, it contains a null value even though it was assigned to a variable. I am trying to keep the value that was created in one function to use in another function multiple times. Thank you.
Set-strictMode -off
[void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
[System.Windows.Forms.Application]::EnableVisualStyles()
Add-Type -AssemblyName System.Web
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
$global:startDate=$null
$global:endDate=$null
function MakeForm{
#region begin GUI
$Form = New-Object system.Windows.Forms.Form
$Form.ClientSize = '396,180'
$Form.text = "Rexpii Integrations Version (Beta)"
$Form.BackColor = "#ffffff"
$Form.TopMost = $False
$Form.Icon= [System.Drawing.Icon]::ExtractAssociatedIcon('C:\files\scripts\tpgicon.ico')
$btnSubmit = New-Object system.Windows.Forms.Button
$btnSubmit.text = "Submit"
$btnSubmit.width = 60
$btnSubmit.height = 30
$btnSubmit.location = New-Object System.Drawing.Point(220,116)
$btnSubmit.Font = 'Microsoft Sans Serif,10'
$btnSubmit.Add_Click({
$global:startDate= $Global:txtStartDate.Value.ToString("yyyy-MM-dd")
$global:endDate= $Global:txtEndDate.Value.ToString("yyyy-MM-dd")
GetData
$Form.Close()})
$btnCancel = New-Object system.Windows.Forms.Button
$btnCancel.text = "Cancel"
$btnCancel.width = 60
$btnCancel.height = 30
$btnCancel.location = New-Object System.Drawing.Point(288,116)
$btnCancel.Font = 'Microsoft Sans Serif,10'
$btnCancel.Add_Click({
$Form.Close()
})
$Global:txtStartDate = New-Object system.Windows.Forms.DateTimePicker
$Global:txtStartDate.width = 150
$Global:txtStartDate.location = New-Object System.Drawing.Point(208,40)
$Global:txtStartDate.Format = "Custom"
$Global:txtstartDate.CustomFormat = "yyyy-MM-dd"
$Global:txtEndDate = New-Object system.Windows.Forms.DateTimePicker
$Global:txtEndDate.width = 150
$Global:txtEndDate.location = New-Object System.Drawing.Point(208,80)
$Global:txtEndDate.Format="Custom"
$Global:txtEndDate.CustomFormat = "yyyy-MM-dd"
$Form.controls.AddRange(#($btnSubmit,$btnCancel,$PictureBox1,$PictureBox2,$StartDate,$EndDate,$lblStartDate,$lblEndDate,$txtStartDate, $txtEndDate))
[void]$Form.ShowDialog()
}
MakeForm
function GetData{
#my scripts number one
Write-Output "This is the first $global:startDate to $global:endDate example"
#my scripts number two
Write-Output "This is the second $global:startDate to $global:endDate example"
}
First, you need to define your functions before you can use them. You are trying to call GetData before it's defined. Move the call to MakeForm (which also shows the form) to after the function definition for GetData.
Second, should change GetData to call Write-Host instead of Write-Output so you can see the output from the event handler. And if you call GetData after showing the form, you'll see that the globals are set properly.
So the last part of your script should look like:
function GetData{
#my scripts number one
Write-Host "This is the first $global:startDate to $global:endDate example"
#my scripts number two
Write-Host "This is the second $global:startDate to $global:endDate example"
}
MakeForm
# Call GetData again to verify that the globals are set.
GetData