こんにちは SharePoint サポートの森 健吾 (kenmori) です。
今回の投稿では、SharePoint Online のブログ サイトで、リストの新規作成フォーム、編集フォーム、表示フォームを再作成する方法をご紹介します。
画面からリスト フォームの Web パーツを削除してしまった場合、画面上で Web パーツが消失するだけでなく、リストのフォーム定自体が消失します。
その結果、 特に予定表リストなど内部処理でフォームの定義 (SPList.Forms プロパティ) が参照されるような処理が実行されたた場合、エラーが発生する場合があります。
オンプレミス版の対処策は下記ページでも公開されており、このページに記載されているSharePoint Designer による対処策は SharePoint Online でも使用できます。
タイトル : SharePoint 2013 リスト アイテムの新規作成フォーム、編集フォーム、表示フォームを作成する
アドレス: http://blogs.technet.com/b/sharepoint_support/archive/2015/06/22/sharepoint-2013-create-a-new-form-for-a-list-item.aspx
しかしながら、SharePoint Designer での対処策ではフォームの機能を有する別のユーザー定義フォームの Web パーツを貼り付ける形式ですので見た目での対処には至りますが、リストのフォーム定義は消失したままとなりますため、完全な対処策にならない場合があります。
結果的に、PowerShell による完全対策を希望される場合が多いためSharePoint Online 向けの修正方法も記載します。
実行手順
1. テキスト エディタを開き、下記の内容を FixListView.ps1 として保存します。
param(
$siteUrl,
$listName,
$username,
$password,
$formtype = "ALL",
$force = $false
)
$ErrorActionPreference = "Stop"
[void][System.Reflection.Assembly]::Load("Microsoft.SharePoint.Client, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
[void][System.Reflection.Assembly]::Load("Microsoft.SharePoint.Client.Runtime, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
$context = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl)
$secpass = ConvertTo-SecureString $password -AsPlainText -Force
$context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $secpass)
$web = $context.Web
$list = $web.Lists.GetByTitle($listName)
$context.Load($list)
$context.ExecuteQuery()
$parentFolder = $list.RootFolder
$context.Load($parentFolder)
$context.ExecuteQuery()
if ($list.BaseType -eq [Microsoft.SharePoint.Client.BaseType]::DocumentLibrary)
{
$formsurl = $parentFolder.ServerRelativeUrl + "/Forms"
$parentFolder = $web.GetFolderByServerRelativeUrl($formsurl)
$context.Load($parentFolder)
$context.ExecuteQuery()
}
function CreateView($fileName, $ControlMode, $FormType)
{
$url = $parentFolder.ServerRelativeUrl + "/" + $fileName
$fileType = [Microsoft.SharePoint.Client.TemplateFileType]::FormPage
$checkfile = $web.GetFileByServerRelativeUrl($url)
$context.Load($checkfile)
try
{
$context.ExecuteQuery()
$fileExists = $checkfile.Exists
}
catch{}
if ($force)
{
if ($fileExists)
{
$checkfile.DeleteObject()
$context.ExecuteQuery()
}
$file = $parentFolder.Files.AddTemplateFile($url, $fileType)
$context.Load($file)
$context.ExecuteQuery()
}
else
{
Write-Host $url "already exists. You may have duplicate list forms now."
$file = $checkfile
}
$wpm = $file.GetLimitedWebPartManager([Microsoft.SharePoint.Client.WebParts.PersonalizationScope]::Shared)
$webPartXml = '<?xml version="1.0" encoding="utf-8"?>'
$webPartXml += '<WebPart xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/WebPart/v2">'
$webPartXml += '<Title>' + $list.Title + '</Title>'
$webPartXml += '<FrameType>Default</FrameType>'
$webPartXml += '<Description/>'
$webPartXml += '<IsIncluded>true</IsIncluded>'
$webPartXml += '<PartOrder>2</PartOrder>'
$webPartXml += '<FrameState>Normal</FrameState>'
$webPartXml += '<Height/>'
$webPartXml += '<Width/>'
$webPartXml += '<AllowRemove>true</AllowRemove>'
$webPartXml += '<AllowZoneChange>true</AllowZoneChange>'
$webPartXml += '<AllowMinimize>true</AllowMinimize>'
$webPartXml += '<AllowConnect>true</AllowConnect>'
$webPartXml += '<AllowEdit>true</AllowEdit>'
$webPartXml += '<AllowHide>true</AllowHide>'
$webPartXml += '<IsVisible>true</IsVisible>'
$webPartXml += '<DetailLink/>'
$webPartXml += '<HelpLink/>'
$webPartXml += '<HelpMode>Modeless</HelpMode>'
$webPartXml += '<Dir>Default</Dir>'
$webPartXml += '<PartImageSmall />'
$webPartXml += '<MissingAssembly>Cannot import this Web Part.</MissingAssembly>'
$webPartXml += '<PartImageLarge/>'
$webPartXml += '<IsIncludedFilter/>'
$webPartXml += '<Assembly>Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>'
$webPartXml += '<TypeName>Microsoft.SharePoint.WebPartPages.ListFormWebPart</TypeName>'
$webPartXml += '<ListName xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">{' + $list.ID.ToString() + '}</ListName>'
$webPartXml += '<ListId xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">' + $list.ID.ToString() + '</ListId>'
$webPartXml += '<ControlMode xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">' + $ControlMode + '</ControlMode>'
$webPartXml += '<TemplateName xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">ListForm</TemplateName>'
$webPartXml += '<FormType xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">' + $FormType + '</FormType>'
$webPartXml += '<ViewFlag xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">1048576</ViewFlag>'
$webPartXml += '</WebPart>'
$webPartDefinition = $wpm.ImportWebPart($webPartXml)
$webPart = $webPartDefinition.WebPart
[void]$wpm.AddWebPart($webPart, "Main", 1)
$context.Load($webPart)
$context.ExecuteQuery()
}
$formtype = $formtype.ToUpper()
if (($formtype -eq "ALL") -or ($formtype -eq "DISPLAY"))
{
CreateView -fileName "DispForm.aspx" -ControlMode "Display" -FormType "4"
}
if (($formtype -eq "ALL") -or ($formtype -eq "EDIT"))
{
CreateView -fileName "EditForm.aspx" -ControlMode "Edit" -FormType "6"
}
if (($formtype -eq "ALL") -or ($formtype -eq "NEW"))
{
CreateView -fileName "NewForm.aspx" -ControlMode "New" -FormType "8"
}
2. 下記のように実行します。
.\fixlistview.ps1 -siteurl https://tenant.sharepoint.com -listName "リスト名" -username user@tenant.onmicrosoft.com -password password -formtype DISPLAY -force $true
パラメータの説明
-siteurl ・・・ サイトの URL
-listname ・・・ リストのタイトル
-username ・・・ 実行ユーザーのログイン名
-password ・・・ 上記ユーザーのパスワード
-formtype ・・・ 修復するフォーム タイプ DISPLAY, NEW, EDIT, ALL (省略した場合は ALL)
-force ・・・ 既存のページにフォームを配置する場合は -force $false, ページを再作成してフォームを再配置する場合 -force $true (省略した場合は $false)
※ 注意
SharePoint オンプレミス版と異なり、IListWebPart など公開されたクラスが存在しているわけではありません。XML を自身で作成して配置した方法ですので、今後のアップデートによっては正常動作しなくなる可能性があります。
ご使用前にテスト用のリストを用意し、事前に動作を確認した上で、有効と判断される場合はご使用いただくことをお勧めします。
今回の投稿は以上になります。