VBScriptベースのHTAで入力フォームを増やしたり減らしたりする

環境：windows10

　HTAは知名度が低いですが，windowsでHTML形式でアプリを作成できる機能です。
　メモ帳だけでGUIアプリが作成できるので，主にVBScriptでメッセージボックス以上のGUIが必要になったら選択肢の一つになります（実際はExcelでVBEに記述して，VBScriptに書き下して，HTAに挿入というのがよいと思います。開発環境が使えない人のための最大限効率のよい開発手法について別記事にしようと思ってます）。
　PowerShellとどっちがいいか，という点については，開発環境や機能ではPowerShellの方が優れていますが，PowerShellは配布時に起動用のバッチファイルが必要になったり,
https://qiita.com/harryyuni/items/c7095d0e472d50fdc35e
オブジェクト渡しの関係で遅く，MicrosoftOfficeやIEへのアクセスはVBScriptの方が優れているので，配布を考えたときにはHTAでの開発がよいケースも依然としてあります。

　HTAはだいぶ古い技術ですが，マイクロソフト公式にヘッダーの指定やフォームの追加について書かれていて，検索窓で「HTA」と検索すると参考になります。
　https://docs.microsoft.com/en-us/previous-versions/ms536495(v=vs.85)
（マイクロソフト公式）
　VBScriptベースの開発用の本ならこちらが参考になります。[VBScript Hackers Technique Webクライアント・アプリケーションの制作―](
https://www.amazon.co.jp/VBScript-Hackers-Technique-Web%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%83%BB%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E5%88%B6%E4%BD%9C%E2%80%95HTML%E3%80%81HTA%E3%80%81XML%E3%80%81Ajax%E3%82%92%E9%A7%86%E4%BD%BF%E3%81%97%E3%81%9FWeb2-0%E6%99%82%E4%BB%A3%E3%81%AE%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0Tips-%E4%BD%90%E8%97%A4/dp/4896272978)
（アマゾン）

#概要
追加ボタンで増えて，削除ボタンで減る，よくある実装です。
![2021-02-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/af42bde7-8aae-405a-f8b3-ab91a6ef7d6a.png)
![2021-02-08 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/18682554-a91d-ae96-33ff-6236356a850b.png)


#スクリプト
　以下の内容でメモ帳の拡張子を.htaにして保存すればすぐに使用できます。
　保存時の「文字コード」は「ANSI」にしないと文字化けします。このあたりはVBScriptと一緒です。
![2021-02-07 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/3b7c6ab8-bd58-1852-be51-0234696bbb64.png)

```html:hta
<html><head>
<title>フォームの増減</title></head>
<body>
<p id="product" name="productParent">
物品<input type="text" name="product"/></p>
<input type="button" name="add" value="追加" onClick=clone_tag("product") />
<input type="button" name="remove" value="削除" onClick=remove_tag("product") />
<br>

<script language="VBScript">
Sub clone_tag(parentId)
	Dim parentTagsNum
	parentTagsNum=document.getElementsByName(parentId).Length
	Dim lastParentId
		If parentTagsNum = 2 Then
			lastParentId = parentId
		Else
			lastParentId = parentId & parentTagsNum - 1
		End if
	Dim parentTag
	Set parentTag=document.getElementById(lastParentId)
	Dim cloneTag
	Set cloneTag=parentTag.cloneNode(true)
	cloneTag.Id=parentId & parentTagsNum
	parentTag.appendchild(cloneTag)
End Sub
Sub remove_tag(parentId)
	Dim parentTagsNum
	parentTagsNum=document.getElementsByName(parentId).Length
	Dim lastParentId,deleteChildId
		If parentTagsNum = 2 Then
			Exit Sub
		Elseif parentTagsNum = 3 Then
			lastParentId = parentId
			deleteChildId = parentId & parentTagsNum - 1
		Else
			lastParentId = parentId & parentTagsNum - 2
			deleteChildId = parentId & parentTagsNum - 1
		End if
	Dim lastParentTag
	Set lastParentTag=document.getElementById(lastParentId)
	Dim deleteChildTag
	Set deleteChildTag=document.getElementById(deleteChildId)
	lastParentTag.removeChild(deleteChildTag)
End Sub
</script>
</body>
</html>
```

#補足
追加ボタン

```vb:hta
Sub clone_tag(parentId)
	Dim parentTagsNum
	parentTagsNum=document.getElementsByName(parentId).Length
	Dim lastParentId
		If parentTagsNum = 2 Then
			lastParentId = parentId
		Else
			lastParentId = parentId & parentTagsNum - 1
		End if
	Dim parentTag
	Set parentTag=document.getElementById(lastParentId)
	Dim cloneTag
	Set cloneTag=parentTag.cloneNode(true)
	cloneTag.Id=parentId & parentTagsNum
	parentTag.appendchild(cloneTag)
End Sub

```
　親タグの要素数で直近の親のIdを特定して，子要素を加える実装です。
　親タグの要素数は，pタグとinputタグで最初が２です。
　なので，タグが２のときはそのままのId，３以降は生成時に指定したIdで特定しています。
　どうも，HTAでは使えるメソッドなどに制限があるようです。
　.appendchildは使えますが，.Afterはエラーになったのでどんどん子要素を増やす実装になっています。
　僕の技術不足で動かせなかった可能性はあります。

削除ボタン

```vb:hta
Sub remove_tag(parentId)
	Dim parentTagsNum
	parentTagsNum=document.getElementsByName(parentId).Length
	Dim lastParentId,deleteChildId
		If parentTagsNum = 2 Then
			Exit Sub
		Elseif parentTagsNum = 3 Then
			lastParentId = parentId
			deleteChildId = parentId & parentTagsNum - 1
		Else
			lastParentId = parentId & parentTagsNum - 2
			deleteChildId = parentId & parentTagsNum - 1
		End if
	Dim lastParentTag
	Set lastParentTag=document.getElementById(lastParentId)
	Dim deleteChildTag
	Set deleteChildTag=document.getElementById(deleteChildId)
	lastParentTag.removeChild(deleteChildTag)
End Sub
```
　こちらは，親タグ，子タグを特定して削除するので，３のときに元々のIdを，４以上のときに指定したIdで.removeChildを実行します。
　全く追加していない２のときは削除すると項目がなくなってしまうので，条件分岐しておきます。