0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Classic ASPでハマった「Split × UBound」問題とEmptyの罠

0
Posted at

はじめに

自己の立場を軽く。
新卒から2年目までWEB系のバック、フロントエンドをRubyで経験。
4年異業種を経験し、再度IT職のSESへ転職しました。
そこでVue、REACTなどモダンな言語を数カ月経験した後に、
現在のASPclassicにアサインという流れになります。

この記事の対象者

•モダンな言語から、レガシー言語へ向き合う方
•基幹業務などの開発案件にアサインされた方
•エンジニア経験の浅い方(己)
•過去の自分に向けて

背景

更新、削除処理で以下の流れを回してます。
表示処理ではなく、ユーザーのアクション処理になります。

1. SQLで取得した各列の値を
2. カンマ区切りの文字列に連結し
3. hidden inputに格納
4. フォーム送信
5. サーバー側でSplitして配列化
6. 同じインデックスを1レコードとして扱う

問題

今回は、工程5で空文字としての配列が入ってほしかったです。
しかし、UboundとSplitの組み合わせでエラーとなりました。

  • HTML側のhidden input例
    ここではvalue属性は空文字 "" に設定されている

サンプルコード

<input type="hidden" id="hidKey" name="hidKey" value="">
  • Classic ASP側での受け取り
' フォームから受け取ったカンマ区切りデータを配列化
arrKey      = Split(Request.Form("hidKey"), ",")
arrName     = Split(Request.Form("hidName"), ",")
arrCategory = Split(Request.Form("hidCategory"), ",")
arrCount    = Split(Request.Form("hidCount"), ",")

' 基準となる配列の要素数でループ
For i = 0 To UBound(arrKey)

    ' 1レコード分のデータを組み立て
    ReDim record(3)
    record(0) = arrKey(i)
    record(1) = arrName(i)   ' ここでエラー
    record(2) = arrCategory(i)
    record(3) = arrCount(i)

    ' 件数チェックなどの事前処理
    sqlInfo = BuildCheckSQL(record)
    Set rs = ExecuteQuery(sqlInfo("SQL"), sqlInfo("Params"))

    If Not rs.EOF Then
        existingCount = rs(0).Value
    End If
    rs.Close

    ' 条件に応じて削除処理
    If existingCount > 0 Then
        ExecuteDelete(record)
    End If

Next

配列が同じ要素数になることが前提のため、
1つでもから配列になると下記でエラーが出てしまいます。

For i = 0 To UBound(arrKey)

通常は、Request.Form("hidCname") が空文字 "" の場合
Split("") → Array("") → UBound=0
arr(0) は空文字 "" を参照してほしいです。

しかし、今回UBound(Sname) = -1 になりました。
0番目を参照すると「Subscript out of range」でエラーになる内容です。

なぜUBound=-1になるのか?

「Empty」と「空文字」の違い

  • Empty
    • 変数が初期化されていない状態
    • 値が設定されていない
    • Variant型
    • Split(Empty, ",") → 空配列(要素0)になる場合がある
      →UBound=-1

   

  • 空文字 ""
    • 値はあるが文字列長が0
    • Split("", ",") → Array("") → 要素数1 → UBound=0
      ⇛「空文字が1要素入った配列」になる

※ UBound = -1 になるのは、
Splitの対象が空文字ではなく「Empty」の場合である

  
なぜhidden inputがEmptyになるか?

  • inputがdisabledになっている
  • ブラウザやJavaScriptでvalueを削除して送信
  • フォーム自体にそのhiddenが送信されなかった
    →この場合、Request.Formで受け取る値が Empty になりうる

改善策

  • Emptyを空文字に変換してからSplit
val = Request.Form("hidName")

If IsEmpty(val) Then
    val = ""
End If

arrName = Split(val, ",")
End If
  • 参照前に必ずチェック
If IsArray(arrName) And UBound(arrName) >= 0 Then
    record(1) = arrName(i)
Else
    record(1) = ""
End If

まとめ

今回は、alue='' に見える hidden input を、ASP側で Empty として受け取ったためUBoud=-1 になりました

  • Classic ASPでhidden inputの値がEmptyの場合、Splitで空配列となりUBound=-1になります
  • 空文字 "" と Empty は異なります
  • UBound参照前には必ず IsEmpty / UBoundチェックを行うのが吉?
  • Empty → "" に置き換えてからSplitという対処を行いました
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?