{}const=>[]async()letfn</>var
1C開発

1C の変数とデータ型:メモリに保存されているものとそれが重要な理由

プリミティブ型やスコープから参照型、コレクション、型キャスティングの落とし穴まで、組み込み言語1Cの変数やデータ型がどのように構成されているかを理解します。最適化のための実例とヒント。

К

Kodik

著者

2分で読める

組み込みの1C言語でコードを書くとき、数値、文字列、参照要素への参照など、すべての値がどこかに存在します。それはRAMに置かれ、特定のタイプを持ち、特定のルールに従います。 理解 1C の変数とデータ型の仕組みは、基礎です、これがなければ、信頼性の高い効率的なコードを書くことはできません。この記事では、変数の宣言から複合型の扱いの細かい点まで、すべてを順番に説明します。

1Cの変数とは何ですか?

変数は、値が格納されている名前付きのメモリ領域です。1Cでは、変数は動的に型指定されます。どのデータ型がその中にあるかを事前に指定する必要はありません。同じ変数に、最初に数値、次に文字列、次に日付を含めることができます。

キーワード Перем を使用して変数を明示的に宣言することも、単に値を割り当てることによって暗黙的に宣言することもできます。

// 明示的な宣言変数カウンター;

// 割り当てによる暗黙の宣言
Счётчик = 0;
Имя = "Alexey";
ДатаНачала = '20250101';

変数が Перем を介して宣言されているが、まだ値が割り当てられていない場合、変数には特別な値 Неопределено が含まれます。これは重要なポイントです。Неопределеноはゼロでも、空の文字列でも、エラーでもありません。これは独立したデータ型であり、値がないことを意味します。

🔥 10万人以上の学生が参加中

理論を読むのに疲れた?
コーディングの時間だ!

Kodik — 実践でプログラミングを学ぶアプリ。AIメンター、インタラクティブなレッスン、実際のプロジェクト。

🤖 AI 24時間
🎓 修了証
💰 無料
🚀 始める
今日参加

スコープ: 変数が存在する場所

1C には、変数の可視性のレベルが 3 つあります。

モジュールの変数 モジュールの先頭(プロシージャと関数の前)で Перем を介して宣言されます。これらは、このモジュールの任意のプロシージャおよび関数から利用でき、モジュール自体が存在する限り存在します。これは、単一のオブジェクト内のグローバル変数の類似物です。

ローカル変数 プロシージャまたは関数内で作成されます。呼び出されると生まれ、終了すると死にます。占有していたメモリは自動的に解放されます。

エクスポート変数 は、キーワードЭкспортでマークされたモジュール変数です。これらは外部から、つまり他のモジュールやフォームから利用できます。

Перем ГлобальнаяНастройка Экспорт;

ヒント: 大きな値のテーブルをモジュール変数に保存すると、フォームまたは処理のライフタイム全体を通してメモリにハングアップします。実行時にのみデータが必要な場合は、プロシージャ内のローカル変数の方がはるかに安全な選択です。

プリミティブデータ型

1Cプラットフォームは、他のすべての構成要素であるいくつかの基本(プリミティブ)タイプを提供します。

—整数と分数を格納します。最大桁数は38桁で、そのうち10桁までを小数点以下にすることができます。1Cは、ほとんどのプログラミング言語のように浮動小数点の2進数ではなく、10進数の計算を使用します。つまり、1Cの0.1 + 0.2は、JavaScriptやPythonのように0.30000000000000004ではなく、0.3を返します。財務計算において、これは非常に重要な特性です。

Цена = 1500.50;
Количество = 3;
Сумма = Цена * Количество; // 4501.50 — 正確、エラーなし

- UTF-16エンコードの文字列。1Cの文字列は変更できません。連結操作ごとにメモリに新しい文字列が作成されます。ループで何千行も結合すると、各イテレーションで新しいオブジェクトが生成され、古いオブジェクトはガベージコレクターを待ちます。テキストを一括で組み立てるには、ТекстовыйДокумент のエントリを使用するか、配列内のパーツを形成してから結合することをお勧めします。

// 悪い - メモリの二次複雑さ
Результат = "";
Для Каждого Элемент Из Коллекция Цикл
    Результат = Результат + Элемент + ", ";
КонецЦикла;

// 線形の複雑さがより良い
Части = Новый Массив;
Для Каждого Элемент Из Коллекция Цикл
    Части.Добавить(Элемент);
КонецЦикла;
Результат = СтрСоединить(Части, ", ");

日付 — 秒単位の精度で日付と時刻を保存します。空の日付は '00010101' であり、Неопределено ではありません。これはよくあるエラーの原因です。Если Дата = Неопределеноチェックでは空の日付はキャッチされません。正しいチェック:

Если ДатаДокумента = '00010101' Тогда
    // 日付が入力されていません。終了。もしも;

ブレボИстина または Ложь の値をとります。条件式では、1Cは暗黙の型変換を実行しません。つまり、JavaScriptのように、0の数値が自動的にЛожьに変換されることはありません。明示的な比較を書く必要があります。

未定義 -単一の値を持つ特別なタイプ。値がないことを示すマーカーとして使用され、存在しないマッチングキーを参照したり、空の詳細を読んだり、その他同様の状況で返されます。

Null — データベースに関連するもう1つの特別なタイプ。左の接続が使用されており、結合されたテーブルに対応するレコードがない場合に、クエリ結果を処理するときに表示されます。NullНеопределено は異なるものであり、混同しないでください。

参照タイプ:変数に実際にあるものは何ですか?

ディレクトリの要素またはドキュメントを受け取ると、変数にはオブジェクト全体ではなく、プラットフォームがデータベース内のデータを見つけることができる一意の識別子(UUID)が格納されます。

СсылкаНаТовар = Справочники.Товары.НайтиПоКоду("00001");

変数 СсылкаНаТовар には、СправочникСсылка.Товары というタイプの参照が含まれています。これはコンパクトなオブジェクトであり、実際にはGUIDのラッパーです。データ自体(名前、価格、残高)はメモリにロードされません。属性に最初にアクセスしたときにのみ、データベースから取得されます。

// データベースへのアクセスはここで行われます
Наименование = СсылкаНаТовар.Наименование;

これは遅延読み込みと呼ばれ、逆の側面があります。ループ内で 1,000 個のリンクをループし、それぞれのリンクでドットを介してプロパティを読み取る場合、プラットフォームはデータベースに対して 1,000 個の個別のクエリを実行します。正しい解決策は、クエリを介してデータをバッチで受信することです。

// 悪い - データベースへの1000回の呼び出し。それぞれのリンクの配列からのリンク。サイクル
    Наименование = Ссылка.Наименование; // 各イテレーションでのデータベースへのクエリサイクルの終了;

// 良い — データベースへの 1 件のリクエスト
Запрос = Новый Запрос;
Запрос.Текст = "SELECT Name FROM Reference.Book.Products WHERE Link (&List)";
Запрос.УстановитьПараметр("List", МассивСсылок);
Результат = Запрос.Выполнить().Выгрузить();

重要: リンク(СправочникСсылка)は、読み取り専用のデータへの「ポインタ」です。オブジェクト(СправочникОбъект)は、メモリにロードされたデータの完全なコピーであり、変更および書き込みが可能です。オブジェクトは参照よりも重いです。ループ内でオブジェクトを取得しても変更しない場合は、参照とクエリを使用します。

// オブジェクトを取得します。すべてのデータがメモリにロードされます
ОбъектТовара = СсылкаНаТовар.ПолучитьОбъект();
ОбъектТовара.Наименование = "New name";
ОбъектТовара.Записать();

複合型: 1 つのフィールドで多くの可能性

1Cメタデータでは、プロパティは複合型の場合があります。たとえば、ドキュメントの「所有者」フィールドは、СправочникСсылка.ОрганизацииСправочникСсылка.ФизическиеЛица の両方のタイプにすることができます。プラットフォームは、このフィールドに値自体とそのタイプに関する情報の両方を保存します。

複合型を操作するには、オブジェクト ОписаниеТипов を使用します。

МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Number"));
МассивТипов.Добавить(Тип("Line"));

ОписаниеДопустимыхТипов = Новый ОписаниеТипов(МассивТипов);

変数の現在の値のタイプは、ТипЗнч()関数を使用して確認できます。

Если ТипЗнч(Значение) = Тип("Number") Тогда
    // 数値として扱う。それ以外の場合、もしTypeZnh (値) = Type ("DirectoryLink.Goods") なら    // 参照として機能します。

複合型は便利ですが、それなりのコストがかかります。データベースでは、複合型のフィールドは、固定型のフィールドよりも効率が悪くなります。フィールドに常に同じタイプの値が含まれている場合は、構成でそのように指定することをお勧めします。これにより、スペースを節約し、クエリを高速化できます。

コレクション:配列、構造、マッチング

プリミティブタイプと参照タイプに加えて、1Cにはどこでも使用されるユニバーサルコレクションのセットがあります。

配列 - インデックスアクセスを備えた順序付きの値のセット。インデックスはゼロから始まります。任意のタイプの要素を同時に含めることができます。

Список = Новый Массив;
Список.Добавить(42);
Список.Добавить("text");
Список.Добавить(ТекущаяДата());

構造 - キーと値のペアのセット。キーは作成時に指定された文字列です。構造は、名前付きパラメータを送信するのに便利です。

Параметры = Новый Структура;
Параметры.Вставить("Organization", СсылкаОрганизации);
Параметры.Вставить("Period", ТекущаяДата());

適合性 - これもキーと値のペアですが、キーはリンクを含む任意のタイプの値にすることができます。マッチングはハッシュテーブルのように機能します。

КэшНаименований = Новый Соответствие;
КэшНаименований.Вставить(СсылкаНаТовар, "Milk 3.2%");
Наименование = КэшНаименований.Получить(СсылкаНаТовар); // 「牛乳3.2%」

ニュアンス: キーが見つからない場合、マッチのメソッド Получить はエラーを引き起こすのではなく、Неопределено を返します。これは、条件を書くときに考慮する必要があります。

値の表 — 1Cで最も強力なコレクション。基本的に、これは行と型指定された列を持つメモリ内の一時テーブルです。値の表は、データ処理、レポート生成、およびモジュール間の交換に積極的に使用されます。

ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Product", Новый ОписаниеТипов("ReferenceLink.Products"));
ТЗ.Колонки.Добавить("Quantity", Новый ОписаниеТипов("Number"));

НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Товар = СсылкаНаТовар;
НоваяСтрока.Количество = 10;

値のテーブルは、かなりの量のメモリを占める可能性があります。100万行のクエリ結果をテーブルにロードすると、すべての情報がサーバーのRAMに格納されます。大量のデータの場合は、すべてを一度にテーブルにロードするのではなく、Выборкаを介してクエリ結果を一部分ごとに処理することをお勧めします。

型のキャストと落とし穴

1C は、一部の操作で暗黙的に型変換を行うため、予期しない結果になる可能性があります。

// 文字列 + 数字 — エラーになります!
Результат = "Total: " + 100; // タイプキャストエラー

// 正しい — 明示的なキャスト
Результат = "Total: " + Строка(100); // 「合計:100」

// 異なるタイプの比較 0 = 偽 ならば // 偽 — タイプが一致しない 終了 ならば;

Если 0 = "" Тогда     // もし、嘘の終わりであれば、

明示的なキャスト関数はあなたの友人です: Число(), Строка(), Дата(), Булево(). 値を変換する必要があるときは常にそれらを使用し、プラットフォームの自動化に頼らないでください。

パラメータの転送:値と参照による

1Cでは、デフォルトのプロシージャと関数のパラメータは参照によって渡されます。つまり、配列をプロシージャに渡して要素を追加すると、呼び出し元のコードにこれらの変更が反映されます。

Процедура ДобавитьЭлемент(МойМассив)
    МойМассив.Добавить("new item");
КонецПроцедуры

Данные = Новый Массив;
ДобавитьЭлемент(Данные);
// データに「新しい要素」が含まれるようになりました

元のコードを変更から保護するには、キーワード Знач を使用します。

Процедура БезопаснаяОбработка(Знач МойМассив)
    МойМассив.Добавить("this will not affect the original");
КонецПроцедуры

ただし、プリミティブ型(数値、文字列、日付、ブール値)の場合、「参照による」転送は異なる方法で機能します。つまり、プロシージャ内でパラメータを再割り当てしても、外部変数には影響しません。変更は、配列、構造、値の表などの可変オブジェクトに対してのみ表示されます。

なぜこれが重要なのでしょうか?

変数とデータ型を理解することは、学術的な演習ではありません。これはコードの品質に直接影響します。文字列が変更不可能であることを知ることは、メモリ内に何千もの中間オブジェクトを作成することからあなたを救います。参照とオブジェクトの違いを理解することで、データベースへの不要なクエリを何百回も防ぐことができます。複合型の仕組みを理解することは、メタデータ構造を正しく設計するのに役立ちます。スコープの明確な理解は、サーバーコードのメモリリークを防ぎます。

変数を宣言するたびに、何を保存し、どこに保存し、どのくらいの期間保存するかについてのアーキテクチャ上の決定を下します。プラットフォームの内部メカニズムをよく理解すればするほど、コードはより自信を持って効率的になります。


プログラミングを基礎から高度なトピックまで体系的に学びたい場合は、アプリケーションをご覧ください コディックこれは、Python、JavaScript、HTML、CSS、その他の言語のステップバイステップのコースを備えた教育プラットフォームであり、知識の強固な基盤を構築するのに役立ちます。

質問がある場合や、他の開発者と資料について話し合いたい場合は、 Telegramチャンネル、2000人以上の参加者が経験を共有し、お互いの職業上の成長を助け合っています。

🎯先延ばしをやめよう

記事は気に入った?
実践の時間だ!

Kodikでは読むだけでなく、すぐにコードを書く。理論 + 実践 = 本当のスキル。

即座に実践
🧠AIがコードを説明
🏆修了証

登録不要 • カード不要