VB6

【VB6】CInt

VB6 の CInt の挙動

VB6 の CInt 関数の挙動解説

1️⃣ 基本概要

  • 関数名: CInt
  • 目的: 任意の値を 16bit 整数(Integer)に変換する
  • 型範囲: -32,768 ~ 32,767
  • 用途: 数値や文字列、日付などを整数に変換したいときに使用

2️⃣ 型ごとの挙動

挙動
数値 (Integer, Long, Double, Single, Decimal)小数は四捨五入 (.5 は絶対値大きい方向)
BooleanTrue → -1、False → 0
String数値に変換可能なら四捨五入して整数化、不可ならエラー
Date日付はシリアル値(日数)に変換後、四捨五入して整数化
Nothing / Null変換不可 → エラー
その他の型 (Object 等)文字列化できなければエラー

3️⃣ 四捨五入のルール

  • 正の値: .5 は切り上げ
  • 負の値: -.5 は切り下げ(絶対値大きい方向)

例:

  • CInt(1.4) → 1
  • CInt(1.5) → 2
  • CInt(-1.5) → -2
  • CInt(-1.4) → -1

4️⃣ 日付の変換

  • VB6 の日付型は内部的に OLE Automation 日付シリアル値で管理
    例: #1899/12/30# → 0
    #2025/10/03# → 45569
  • CInt(#2025/10/03#) → 45569

5️⃣ Boolean の変換

  • True = -1、False = 0
  • VB6 はビット演算と論理値互換性のためこの値を採用

6️⃣ 文字列の変換

  • 数値文字列 → 数値として認識し、四捨五入して整数化
  • 非数値文字列 → 例外 (Type mismatch)
  • 空文字列 → 例外

例:

  • CInt(“123.6”) → 124
  • CInt(“1.4”) → 1
  • CInt(“abc”) → エラー

7️⃣ 範囲外の値

  • Integer は16bit範囲
  • 範囲外はオーバーフローエラー

例:

  • CInt(40000) → エラー
  • CInt(-40000) → エラー

8️⃣ まとめ

  • VB6 CInt = 16bit整数に変換 + 四捨五入 + Boolean / 日付 / 文字列特殊処理
  • 特徴:
  1. .5 は絶対値大きい方向に丸め
  2. True = -1, False = 0
  3. 日付 → シリアル値に変換
  4. Null / 非数値文字列 → エラー

補足:

  • VB.NET の CInt は型が 32bit Integer になるが、四捨五入や Boolean の扱いは VB6 とほぼ同じ
  • VB6 → C# / VB.NET 移植では丸め処理や型範囲、Boolean/-1の扱いを忠実に再現する必要あり

実装例(VB6完全互換 CInt)

  • C#
  • VB.NET
using System;
using System.Globalization;

namespace Vb6Compat
{
    /// <summary>
    /// VB6 の変換関数互換ライブラリ
    /// </summary>
    public static class Vb6Conversion
    {
        /// <summary>
        /// VB6 の CInt と同じ規則で任意の値を 16bit 整数に変換します。
        /// </summary>
        /// <param name="value">変換する値</param>
        /// <returns>変換後の Int16 値</returns>
        /// <exception cref="InvalidCastException">変換できない値の場合に発生します</exception>
        /// <exception cref="OverflowException">16bit 範囲外の値の場合に発生します</exception>
        /// <remarks>
        /// - 数値は四捨五入して 16bit 範囲に収めます。
        /// - 小数部 .5 は絶対値大きい方向に丸めます。
        /// - Boolean: True=-1, False=0
        /// - 日付は OLE Automation シリアル値に変換して整数化
        /// - Null / DBNull は例外
        /// </remarks>
        public static short CInt(object value)
        {
            if (value == null || value is DBNull)
                throw new InvalidCastException("Null から CInt に変換できません。");

            switch (Type.GetTypeCode(value.GetType()))
            {
                case TypeCode.Boolean:
                    return (bool)value ? (short)-1 : (short)0;

                case TypeCode.DateTime:
                    double oa = ((DateTime)value).ToOADate();
                    return RoundToInt16(oa);

                case TypeCode.String:
                    double d;
                    if (double.TryParse((string)value, NumberStyles.Any, CultureInfo.CurrentCulture, out d))
                        return RoundToInt16(d);
                    throw new InvalidCastException($"文字列 '{value}' を CInt に変換できません。");

                case TypeCode.SByte:
                case TypeCode.Byte:
                case TypeCode.Int16:
                case TypeCode.Int32:
                case TypeCode.Int64:
                case TypeCode.UInt16:
                case TypeCode.UInt32:
                case TypeCode.UInt64:
                case TypeCode.Single:
                case TypeCode.Double:
                case TypeCode.Decimal:
                    return RoundToInt16(Convert.ToDouble(value, CultureInfo.CurrentCulture));

                default:
                    throw new InvalidCastException($"型 {value.GetType()} を CInt に変換できません。");
            }
        }

        private static short RoundToInt16(double value)
        {
            double rounded = Math.Round(value, MidpointRounding.AwayFromZero);
            if (rounded < short.MinValue || rounded > short.MaxValue)
                throw new OverflowException($"値 {value} は CInt の範囲外です。");
            return (short)rounded;
        }
    }
}
Imports System
Imports System.Globalization

''' <summary>
''' VB6 の変換関数互換ライブラリ
''' </summary>
Public Module Vb6Conversion

    ''' <summary>
    ''' VB6 の CInt と同じ規則で任意の値を 16bit 整数に変換します。
    ''' </summary>
    ''' <param name="value">変換する値</param>
    ''' <returns>変換後の Int16 値</returns>
    ''' <exception cref="InvalidCastException">変換できない値の場合に発生します</exception>
    ''' <exception cref="OverflowException">16bit 範囲外の値の場合に発生します</exception>
    ''' <remarks>
    ''' - 数値は四捨五入して 16bit 範囲に収めます。
    ''' - 小数部 .5 は絶対値大きい方向に丸めます。
    ''' - Boolean: True=-1, False=0
    ''' - 日付は OLE Automation シリアル値に変換して整数化
    ''' - Null / Nothing は例外
    ''' </remarks>
    Public Function CInt(ByVal value As Object) As Short
        If value Is Nothing OrElse TypeOf value Is DBNull Then
            Throw New InvalidCastException("Null から CInt に変換できません。")
        End If

        Select Case Type.GetTypeCode(value.GetType())
            Case TypeCode.Boolean
                Return If(CBool(value), CType(-1, Short), CType(0, Short))

            Case TypeCode.DateTime
                Dim oa As Double = CType(value, DateTime).ToOADate()
                Return RoundToInt16(oa)

            Case TypeCode.String
                Dim d As Double
                If Double.TryParse(CStr(value), NumberStyles.Any, CultureInfo.CurrentCulture, d) Then
                    Return RoundToInt16(d)
                End If
                Throw New InvalidCastException($"文字列 '{value}' を CInt に変換できません。")

            Case TypeCode.SByte, TypeCode.Byte, TypeCode.Int16, TypeCode.Int32, TypeCode.Int64,
                 TypeCode.UInt16, TypeCode.UInt32, TypeCode.UInt64, TypeCode.Single, TypeCode.Double, TypeCode.Decimal
                Return RoundToInt16(Convert.ToDouble(value, CultureInfo.CurrentCulture))

            Case Else
                Throw New InvalidCastException($"型 {value.GetType()} を CInt に変換できません。")
        End Select
    End Function

    Private Function RoundToInt16(ByVal value As Double) As Short
        Dim rounded As Double = Math.Round(value, MidpointRounding.AwayFromZero)
        If rounded < Short.MinValue OrElse rounded > Short.MaxValue Then
            Throw New OverflowException($"値 {value} は CInt の範囲外です。")
        End If
        Return CType(rounded, Short)
    End Function

End Module

VB6と同じ動作チェック例

VB6結果
CInt(1.4)11
CInt(1.5)22
CInt(-1.5)-2-2
CInt(True)-1-1
CInt(False)00
CInt(“123.6”)124124
CInt(#2025/10/03#)4556945569

コメント