Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 可以从变量创建PS自定义对象吗?_Arrays_Powershell_Pscustomobject - Fatal编程技术网

Arrays 可以从变量创建PS自定义对象吗?

Arrays 可以从变量创建PS自定义对象吗?,arrays,powershell,pscustomobject,Arrays,Powershell,Pscustomobject,我在sql server中有一个100列的表,我想使它成为一个不需要在文件中传递所有列来加载的表。我在一个表中指定了列名,然后比较哈希表中的列以找到匹配的列。然后,根据要用于插入文件中数据的数组的匹配创建代码。问题是,它不喜欢调用一个变量来创建自定义对象 我将以下内容存储在一个数组中。例如,在其中的100个示例中,下面的示例通知sqlcolumn2被跳过 sqlcolumn1=if[string]::IsNullOrEmpty$obj.P1-eq$true{$null}else{$obj.P1}

我在sql server中有一个100列的表,我想使它成为一个不需要在文件中传递所有列来加载的表。我在一个表中指定了列名,然后比较哈希表中的列以找到匹配的列。然后,根据要用于插入文件中数据的数组的匹配创建代码。问题是,它不喜欢调用一个变量来创建自定义对象

我将以下内容存储在一个数组中。例如,在其中的100个示例中,下面的示例通知sqlcolumn2被跳过

sqlcolumn1=if[string]::IsNullOrEmpty$obj.P1-eq$true{$null}else{$obj.P1} sqlcolumn3=if[string]::IsNullOrEmpty$obj.P2-eq$true{$null}else{$obj.P2} sqlcolumn4=if[string]::IsNullOrEmpty$obj.P3-eq$true{$null}else{$obj.P3} sqlcolumn5=if[string]::IsNullOrEmpty$obj.P4-eq$true{$null}else{$obj.P4} 以下是阵列:

foreach($line in $Final)
{
    $DataRow = "$($line."TableColumnName") = if ([string]::IsNullOrEmpty(`$obj.$($line."PName")) -eq `$true) {`$null} else {`"`$obj.$($line."PName")`"}"
    $DataArray += $DataRow
}
然后,我尝试将它添加到一个最终数组中,在该数组中,我希望它对每一行数据进行循环,然后从数组中执行插入。即使上面数组中的字符串值是正确的,如果它是手工编码的,我也无法让它识别行并运行

foreach ($obj in $data2)
{
   $test = [PSCustomObject] @{  
   $DataArray = Invoke-Expression $DataArray
}
如果我只是键入$DataArray,它不喜欢这样,因为它需要我已经内置到字符串中的=符号

这是我想做的,甚至是可能的

我试图用各种不同的方式来获取这些数据,有些人向我们发送了100列中的30列,其他的或多或少,没有人使用精确的列来减少每件事的单个脚本

添加更多代码:

Function ArrayCompare() {
 [CmdletBinding()]
 PARAM(
    [Parameter(Mandatory=$True)]$Array1,
    [Parameter(Mandatory=$True)]$A1Match,
    [Parameter(Mandatory=$True)]$Array2,
    [Parameter(Mandatory=$True)]$A2Match)

 $Hash = @{}
 foreach ($Data In $Array1) {
    $Hash[$Data.$A1Match] += ,$Data
 }
 foreach ($Data In $Array2) {
    $Hash[$Data.$A2Match] += ,$Data
 }
 foreach ($KeyValue In $Hash.GetEnumerator()){

    $Match1, $Match2 = $KeyValue.Value.Where( {$_.$A1Match}, 'Split')

        [PSCustomObject]@{
        MatchValue = $KeyValue.Key
        A1Matches = $Match1.Count
        A2Matches = $Match2.Count
        TablePosition = [int]$Match2.TablePosition
        TableColumnName = $Match2.TableColumnName
        #  PName is the P(##) that is a generic ascending column value back to import-excel module.  ColumnA = P1, ColumnB = P2  etc..until no data is detected.  Allows flexibility and not having to know how many columns there are
        PName = $Match1.Name}  
 }
}


$Server = 'ServerName'
$Catalog = 'DBName'
$DestinationTable = 'ImportIntoTableName'

$FileIdentifierID = 10
$FileName = 'Test.xlsx'
$FilePath = 'C:\'

$FullFilePath =  $FilePath + $FileName
$data = Import-Excel -Path $FullFilePath -NoHeader -StartRow 1 # Import- 
Excel Module for working with xlsx excel files
$data2 = Import-Excel -Path $ullFilePath -NoHeader -StartRow 2 # Import- 
Excel Module for working with xlsx excel files

$ExpectedHeaderArray = @()
$HeaderArray = @()
$DataArray = @()
$HeaderDetect = @()

$HeaderDetect = $data | Select-Object -First 1 # Header Row In File

$HeaderDetect | 
ForEach-Object  {
                 $ColumnValue = $_
                 $ColumnValue | 
                 Get-Member -MemberType *Property |
                 Select-Object -ExpandProperty Name |
                 ForEach-Object  {
                                    $HeaderValues = [PSCustomObject]@{
                                    Name = $_
                                    Value = $ColumnValue.$_}
                                    $HeaderArray += $HeaderValues
                                 }
                 } 

# Query below provides a list of all expected file headers and the table 
column name they map to
$Query = "SELECT TableColumnName, FileHeaderName, TablePosition FROM 
dbo.FileHeaders WHERE FileIdentifierID = $($FileIdentifierID)" 
$ds = Invoke-Sqlcmd -ServerInstance $Server -Database $Catalog -Query $Query 
-OutputAs DataSet

$ExpectedHeaderArray =  foreach($Row in $ds.Tables[0].Rows)
    {
    new-object psObject -Property @{ 
        TableColumnName = "$($row.TableColumnName)"
        FileHeaderName = "$($row.FileHeaderName)"
        TablePosition = "$($row.TablePosition)"
    }
}

#Use Function Above
#Bring it together so we know what P(##) goes with which header in file/mapped to table column name
$Result = ArrayCompare -Array1 $HeaderArray -A1Match Value -Array2 $ExpectedHeaderArray -A2Match FileHeaderName  

$Final = $Result | sort TablePosition

foreach($Line in $Final)
{
    $DataRow = "$($Line."TableColumnName") = if ([string]::IsNullOrEmpty(`$obj.$($Line."PName")) -eq `$true) {`$null} else {`"`$obj.$($Line."PName"))`"}"
    $DataArray += $DataRow
}

# The output below is what the code inside the last array would be that I would use to import into excel. 
# The goal is to be dynamic and match headers in the file to the stored header value and import into a table (mapped from header column to table column name)
# The reason for this is before I was here, there were many different "versions" of a layout that was given out.  In the end, it is all one in the same
#    but some send all 100 columns, some only send a handful, some send 80 etc.  I am trying to have everything flow through here vs. 60+ pieces of code/stored procedures/ssis packs


 Write-Output $DataArray    

# Output Sample  -- Note how in the sample, P2 and subsequent skip SQLColumn2 because P2 maps to the header value of position 3 in the sql table and each after is one off.  
# In this example, SqlColumn2 would not be populated

# SqlColumn1 = if ([string]::IsNullOrEmpty($obj.P1) -eq $true) {$null} else {"$obj.P1"}
# SqlColumn3 = if ([string]::IsNullOrEmpty($obj.P2) -eq $true) {$null} else {"$obj.P2"}
# SqlColumn4 = if ([string]::IsNullOrEmpty($obj.P3) -eq $true) {$null} else {"$obj.P3"}
# SqlColumn5 = if ([string]::IsNullOrEmpty($obj.P4) -eq $true) {$null} else {"$obj.P4"}


# I know this doesn't work.  This is where I'm stuck, how to build an array now off of this output from above
foreach ($obj in $data2)
{
   $test = [PSCustomObject] @{  
   $DataArray = Invoke-Expression $DataArray}
}

我想先重新陈述一下你的问题,只是为了确保我能正确理解,我可能不理解

您得到的excel文件如下所示: 您还有一个数据库表,如下所示: 还有一个列映射表,如下图所示,ColumnX在本例中未映射: 您希望使用映射表中的数据将电子表格中的值插入到数据库表中,以便获得以下结果: 因此,让我们加载电子表格,让标题行这次生成有意义的属性名称:

$data=导入Excel-路径。\MySpreadsheet.xlsx; 写入主机$data | ft | out字符串; 校长 ---- ---- ---- P值Q值R 值S值T值U 获取列映射数据我正在以编程方式创建内存中的数据集,但显然您是从数据库中读取数据的:

$mappings=新对象System.Data.DataTable; $null=$mappings.Columns.AddTableColumnName,[string]; $null=$mappings.Columns.AddFileHeaderName,[string]; $null=$mappings.Columns.AddTablePosition,[int]; @ @{TableColumnName=ColumnW;FileHeaderName=HeaderA;TablePosition=1}, @{TableColumnName=ColumnY;FileHeaderName=HeaderB;TablePosition=2}, @{TableColumnName=ColumnZ;FileHeaderName=HeaderC;TablePosition=3} | % { $row=$mappings.NewRow; $row.TableColumnName=$\ TableColumnName; $row.FileHeaderName=$\ux.FileHeaderName; $row.TablePosition=$\表位置; $mappings.Rows.添加$row; } $ds=新对象System.Data.DataSet; $ds.Tables.Add$mappings; 写入主机$ds.Tables[0]| ft | out字符串 TableColumnName文件标题名称TablePosition -------- ------- ------- 专栏W标题1 柱状封头B 2 ColumnZ HeaderC 3 现在,我们可以构建映射对象:

$values=@; $data中的foreach$行 { $properties=[ordered]@{}; $mappings中的foreach$mapping { $properties.Add$mapping.TableColumnName,$row.$$mapping.FileHeaderName; } $values+=新对象PSCustomObject-属性$properties; } 写入主机$values | ft | out字符串 圆柱 ---- ---- ---- P值Q值R 值S值T值U 棘手的是$properties。添加$mapping.TableColumnName,$row.$$mapping.FileHeaderName;-基本上,您可以使用虚线字符串文字或变量访问PowerShell中的对象属性,我不确定确切的功能名称-例如

PS>$myValue=新对象PSCustomObject-Property@{aaa=bbb;ccc=ddd} PS>$myValue.aaa bbb PS>$myProperty=aaa PS>$myValue.$myProperty bbb 因此,$row.$$mapping.FileHeaderName是一个表达式,其计算结果为$mapping.FileHeaderName中命名的$row属性的值

最后,您可以使用现有进程将对象插入数据库

请注意,我无法完全了解您的ArrayCompare实际上在做什么,因此上述方法可能无法100%解决您的问题,但希望您可以自己解决差异,或者留下与所需解决方案不同之处的注释


希望这能有所帮助。

我认为你想做的事情可能是可以做到的,而且大多数情况下
kely不需要构建一个代码字符串来调用调用调用表达式,这可能是不安全的,但是查看i您的输入文件的示例以及如何加载它ii您的映射哈希表iii的示例$DataArray的结果示例会很有用。也许把你的例子缩减到5列而不是100列……我在原来的问题中添加了一些代码,希望这能有所帮助。我不知道为什么格式化被关闭,因为我的代码阻止了整个部分。我正在为映射到Sql表列名的每个文件提取预先确定的列名。希望这是有意义的。可能是杀伤力太大了。如果您需要一个文件,请告诉我……如果不构建SQL列映射表,就很难创建一个文件。谢谢@麦克莱顿
+---+---------+---------+---------+
|   |    A    |    B    |    C    |
+---+---------+---------+---------+
| 1 | HeaderA | HeaderB | HeaderC |
+---+---------+---------+---------+
| 2 | Value P | Value Q | Value R |
+---+---------+---------+---------+
| 3 | Value S | Value T | Value U |
+---+---------+---------+---------+
+---------+---------+---------+---------+
+ ColumnW | ColumnX | ColumnY | ColumnZ |
+---------+---------+---------+---------+
+ ....... | ....... | ....... | ....... |
+---------+---------+---------+---------+
+-----------------+----------------+---------------+
| TableColumnName | FileHeaderName | TablePosition |
+-----------------+----------------+---------------+
|    ColumnW      |    HeaderA     |       1       |
+-----------------+----------------+---------------+
|    ColumnY      |    HeaderB     |       2       |
+-----------------+----------------+---------------+
|    ColumnZ      |    HeaderC     |       3       |
+-----------------+----------------+---------------+
+---------+---------+---------+---------+
+ ColumnW | ColumnX | ColumnY | ColumnZ |
+---------+---------+---------+---------+
+ Value P |   null  | Value Q | Value R |
+---------+---------+---------+---------+
+ Value S |   null  | Value T | Value U |
+---------+---------+---------+---------+