Insert — Процедура Delphi


Содержание

Insert — Процедура Delphi

Delphi syntax:
procedure Insert(Source: string; var S: string; Index: Integer);

Description
In Delphi code, Insert merges Source into S at the position S[index].

�� ���-�� ����� �����, �� ���������� ��� �������. �.�. � ��������� ����� � ������ �������� ������ ����� ������. 6 ��� 06, 11:46����[2848985] �������� | ���������� �������� ����������

Re: ������ Insert �� ������ [new]
6 ��� 06, 11:47����[2848989] �������� | ���������� �������� ����������
Re: ������ Insert �� ������ [new]
dmidek
oper557
����� � �������� ������ �������� ������ ����� ������.
� ��� ������������ �������� ? ������������� ?
�������� �� �������:
procedure Insert(Source: string; var S: string; Index: Integer);

Description
Insert merges Source into S at the position S[index].

6 ��� 06, 11:47����[2848991] �������� | ���������� �������� ����������
Re: ������ Insert �� ������ [new]
oper557
Inserts a substring into a string beginning at a specified point.

Delphi syntax:
procedure Insert(Source: string; var S: string; Index: Integer);

Description
In Delphi code, Insert merges Source into S at the position S[index].

Строки Delphi

Сегодня речь пойдет о строках. Строки в Delphi, на мой взгляд не менее важны, чем числа. Если Вы решили стать программистом, то без строк никуда. Как говорится «из песни слов не выкинешь».

В этой статье мы рассмотрим то, как можно работать со строками. Изучим основные функции, разберем их на примерах. Примеры будут не сложные, но очень полезные. Также попробуем комбинировать строковые функции.

Для начала покажу как определить строку и присвоить ей значение

Разберемся теперь с функциями обработки строк:

Функция Length()

Функция Length() – возвращает количество символов в строке. Выглядит она так:

Function Length(S): Integer;

Передаем один параметр – строку, в результате получаем число символов.

В примере мы выводим сообщение с длиной строки str1.

Функция Copy()

Функция Copy() – функция возвращаем заданный отрывок строки.

function Copy ( str1 : string, Index, Count : Integer ) : string;

  • str1 – строка, из которой мы хотим извлечь часть.
  • Index – порядковый номер начального символа.
  • Count – сколько символов мы хотим извлечь.

Приведу пример и все станет на свои места

Функция Pos()

Функция Pos() – возвращает позицию одной строки в другой. Так сказать, ищет подстроку в строке. Если что-то находит, то возвращает номер символа начиная с которого началось совпадение.

function Pos ( const str2, str1 : string ) : Integer;

  • str2 – строка, которую ищем.
  • str1 – строка, в которой ищем.

Напишем пример, в котором будем искать вхождение «стр» в str1 и выведем найденное число в сообщении.

Процедура Delete()

Процедура Delete() – удаляет часть строки.

procedure Delete ( var Str1 : string; Index : Integer, Count : Integer );

  • str1 – строка из которой удаляем символы.
  • Index – позиция с которой начинаем удалять.
  • Count – сколько символов удаляем

Процедура Insert()

Процедура Insert() – вставляет одну строку в другую, начиная с указанного символа.

procedure Insert(str2: String; var Str1: String; Index: Integer);

  • str2-страка, которую вставляем.
  • str1-строка, в которую вставляем.
  • Index – позиция, с которой начнется вставка

Эти основные функции помогут сделать со строками в delphi любые манипуляции.

Delphi. Эксперименты с INSERT или как добавить запись в середину таблицы БД?

В этом посте напишу о своем опыте с DBExpress MySQL и попыткой INSERT… То есть, хотелось бы научить программу вставлять в любую строку, а не только в последнюю. Но не тут-то было!

В самом простом случае (когда у нас нет ключевых полей) INSERT из DELPHI работает прекрасно… Жмём кнопку INSERT, вставляем запись – сохраняем в физической БД нажатием на SAVE…

Но такая “идилия” длится до тех пор, пока не нажмешь на Refresh…

Как я обработал кнопку INSERT?

Как я обработал кнопку SAVE?

И вроде бы всё Ок! Но, стоило сделать единственное поле экспериментальной таблицы MyTable сделать ключевым, то есть при формировании таблицы написать такой код…

Как тут же я столкнулся с тем, что записи переставляются в алфавитном, либо возрастающем порядке по тому или иному номеру. В нашем случае – одно поле VarChar, поэтому СУБД MySQL сортирует в алфавитном порядке… (хотя впоследствии запись всегда вставлялась в конец.. в общем разбираюсь в данном вопросе)

Проблема

При всех моих попытках идти стандартными способами новая строка всё время вставлялась в конец! Вот как выглядел “стандартный” код для INSERT, который рекомендуют в некоторых онлайн учебниках…

SimpleDataSet1.Insert; SimpleDataSet1.FieldByName(‘Primary_key’).AsInteger:=PK+1; SimpleDataSet1.FieldByName(‘Name’).AsString:=’New Record’; SimpleDataSet1.Post; SimpleDataSet1.ApplyUpdates(-1); SimpleDataSet1.Refresh;

Оканчивалось это так… Запись постоянно оказывалась в конце… Это и понятно! У нас есть ключевое поле в этой таблице и СУБД автоматически упорядочивает записи по нему. Чтобы этого избежать, нужно либо убрать ключевое поле (что немыслимо при разработке серьезного приложения), либо воспользоваться дополнительной колонкой Sort (см. решение проблемы ниже).

Решение

Итак, решение в том, чтобы ввести новый столбец Sort, и далее, умело нумеруя и переставляя записи отображать “всё это дело” пользователю. То есть, примерно таким образом…

Теперь, имея такой столбец, можно вставлять в любое место нашей таблицы, и вот какой результат у нас получится…

Insert — Процедура Delphi

Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда — alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Форум программистов > Delphi > БД в Delphi
процедура Insert
Регистрация
Поиск по форуму
Расширенный поиск
К странице.
Страница 1 из 2 1 2 Следующая >

Здравствуйте, вы не подскажете, что я делаю не так.
База данных, состоящая из одной таблицы, написана в SQL 2005, там же создана процедура:

CREATE PROC InsertPasport
@s_n INT
,@surname VARCHAR(30)
,@name1 VARCHAR(30)
,@name2 VARCHAR(30)
,@birthday DATETIME
,@who_v VARCHAR(500)
,@when_v DATETIME
,@registration VARCHAR(500)
,@adres VARCHAR(500)
,@family VARCHAR(20)
AS
Begin
INSERT INTO Pasport
(S_N, SURNAME, NAME1, NAME2, BIRTHDAY, WHO_V,
WHEN_V, REGISTRATION, ADRES, FAMILY)
VALUES (@s_n, @surname, @name1, @name2, @birthday, @who_v,
@when_v, @registration, @adres, @family)
end
GO

Интерфейс к базе создаётся на Delphi. Проблема в том что при обращении к процедуре “InsertPasport” :

procedure TForm2.FormCreate(Sender: TObject);
begin
ADOQuery1.close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add(‘EXEC InsertPasport’);
ADOQuery1.Open;
ADOQuery1.Active:=true;
end;

Появляется ощибка: Exception class EOleException with message ‘Procedure or Function ‘InsertPasport’ expects parameter ‘@s_n’, which was not supplied’.

SQL Insert Into

Вечер добрый, уважаемые программисты ! делаю лабораторную работу, мне надо сделать 3 кнопки , используя запросы SQ, только начал делать, и уже столкнулся с прблемами , создаю кнопку Инсерт инто.
Суть в том, что вроде запрс написан, компилируется, но при нажатии на инсерт в проекте Тю-тю, выкидывает на диалоговое окно с ошибкой Project Project1 raised exception class EDBEengineError with message ‘General SQL error. MS Драйвер ОДБЦ МС Акссес ошибочная инструкция SQL предполагалось Delete, Insert, Procedure , Select or Update process stopped. Помогите разобраться, буду благодарен любой помощи!

11.08.2009, 19:54 #1
12.02.2013, 19:27

SQL-запрос на Insert
Доброго дня, форумчане. Подскажите, пожалуйста в чем причина разной работы этих двух запросов? .

SQL-запрос долго выполняется (INSERT)
ПРочитал много, так и не нашел вразумительного ответа. Может кто чем поможет. В общем, при.

Ошибочная инструкция SQL, предполагалось delete insert
В общем хочу сделать выборку по диапазону дат, но почему то по моей объеденной таблице.

ADO+MS SQL: как узнать количество обработанных строк при insert в ADO Query?
Добрый день. При выполнении запроса в MS SQL insert into ..(,,) select 0,20,’Text’ where.

Insert — Процедура Delphi

Статья содержит всесторонний обзор основных фактов которые Вы должны знать, прежде чем начать писать программы, работающие с Базами Данных (БД). Прочитав эту статью, Вы должны понять большинство механизмов доступа к данным, которые есть в Delphi.

Более подробно здесь рассказывается о TTable и TDataSource.

Имеются несколько основных компонент(объектов), которые Вы будете использовать постоянно для доступа к БД. Эти объекты могут быть разделены на три группы:

  • невизуальные: TTable, TQuery, TDataSet, TField
  • визуальные: TDBGrid, TDBEdit
  • связующие: TDataSource

Первая группа включает невизуальные классы, которые используются для управления таблицами и запросами. Эта группа сосредотачивается вокруг компонент типа TTable, TQuery, TDataSet и TField. В Палитре Компонент эти объекты расположены на странице Data Acc ess.

Вторая важная группа классов — визуальные, которые показывают данные пользователю, и позволяют ему просматривать и модифицировать их. Эта группа классов включает компоненты типа TDBGrid, TDBEdit, TDBImage и TDBComboBox. В Палитре Компонент эти объекты расположены на странице Data Controls.

Имеется и третий тип, который используется для того, чтобы связать предыдущие два типа объектов. К третьему типу относится только невизуальный компонент TDataSource.

      1. Класс TDataSet
      2. TDataSet класс — один из наиболее важных объектов БД. Чтобы начать работать с ним, Вы должны взглянуть на следующую иерархию:

      TDataSet содержит абстрактные методы там, где должно быть непосредственное управление данными. TDBDataSet знает, как обращаться с паролями и то, что нужно сделать, чтобы присоединить Вас к определенной таблице. TTable знает (т.е. уже все абстрактные методы переписаны), как обращаться с таблицей, ее индексами и т.д.

      Как Вы увидите в далее, TQuery имеет определенные методы для обработки SQL запросов.

      TDataSet — инструмент, который Вы будете использовать чтобы открыть таблицу, и перемещаться по ней. Конечно, Вы никогда не будете непосредственно создавать объект типа TDataSet. Вместо этого, Вы будете использовать TTable, TQuery или других потомков TDataSet (например, TQBE). Полное понимание работы системы, и точное значение TDataSet, будут становиться все более ясными по мере прочтения этой главы.

      На наиболее фундаментальном уровне, Dataset это просто набор записей, как изображено на рис.1

      Рис .1: Любой dataset состоит из ряда записей (каждая содержит N полей) и указатель на текущую запись.

      В большинстве случаев dataset будет иметь a прямое, один к одному, соответствие с физической таблицей, которая существует на диске. Однако, в других случаях Вы можете исполнять запрос или другое действие, возвращающие dataset, который содержит либо любое подмножество записей одной таблицы, либо объединение (join) между несколькими таблицами. В тексте будут иногда использоваться термины DataSet и TTable как синонимы.

      Обычно в программе используются объекты типа TTable или TQuery, поэтому в следующих нескольких главах будет предполагаться существование объекта типа TTable называемого Table1.

      Итак, самое время начать исследование TDataSet. Как только Вы познакомитесь с его возможностями, Вы начнете понимать, какие методы использует Delphi для доступа к данным, хранящимся на диске в виде БД. Ключевой момент здесь — не забывать, что почти всякий раз, когда программист на Delphi открывает таблицу, он будет использовать TTable или TQuery, которые являются просто некоторой надстройкой над TDataSet.

      В этой главе Вы узнаете некоторые факты об открытии и закрытии DataSet.

      Если Вы используете TTable для доступа к таблице, то при открытии данной таблицы заполняются некоторые свойства TTable (количество записей RecordCount, описание структуры таблицы и т.д.).

      Прежде всего, Вы должны поместить во время дизайна на форму объект TTable и указать, с какой таблицей хотите работать. Для этого нужно заполнить в Инспекторе объектов свойства DatabaseName и TableName. В DatabaseName можно либо указать директорию, в которой лежат таблицы в формате dBase или Paradox (например, C:\DELPHI\DEMOS\DATA), либо выбрать из списка псевдоним базы данных (DBDEMOS). Псевдоним базы данных (Alias) определяется в утилите Database Engine Configuration. Теперь, если свойство Active установить в True, то при запуске приложения таблица будет открываться автоматически.

      Имеются два различных способа открыть таблицу во время выполнения программы. Вы можете написать следующую строку кода:

      Или, если Вы предпочитаете, то можете установить свойство Active равное True:

      Нет никакого различия между результатом производимым этими двумя операциями. Метод Open, однако, сам заканчивается установкой свойства Active в True, так что может быть даже чуть более эффективно использовать свойство Active напрямую.

      Также, как имеются два способа открыть a таблицу, так и есть два способа закрыть ее. Самый простой способ просто вызывать Close:

      Или, если Вы желаете, Вы можете написать:

      Еще раз повторим, что нет никакой существенной разницы между двумя этими способами. Вы должны только помнить, что Open и Close это методы (процедуры), а Active — свойство.

      Навигация (Перемещение по записям)

      После открытия a таблицы, следующим шагом Вы должны узнать как перемещаться по записям внутри него.

      Следующий обширный набор методов и свойства TDataSet обеспечивает все , что Вам нужно для доступа к любой конкретной записи внутри таблицы:

      property BOF: Boolean read FBOF;

      property EOF: Boolean read FEOF;

      procedure MoveBy(Distance: Integer);

      Дадим краткий обзор их функциональных возможностей:

      • Вызов Table1.First перемещает Вас к первой записи в таблице.
      • Table1.Last перемещает Вас к последней записи.
      • Table1.Next перемещает Вас на одну запись вперед.
      • Table1.Prior перемещает Вас на одну запись Назад.
      • Вы можете проверять свойства BOF или EOF, чтобы понять, находитесь ли Вы в начале или в конце таблицы.
      • Процедура MoveBy перемещает Вас на N записей вперед или назад в таблице. Нет никакого функционального различия между запросом Table1.Next и вызовом Table1.MoveBy(1). Аналогично, вызов Table1.Prior имеет тот же самый результат, что и вызов Table1.MoveBy(-1 ).

      Чтобы начать использовать эти навигационные методы, Вы должны поместить TTable, TDataSource и TDBGrid на форму, также, как Вы делали это в предыдущем уроке. Присоедините DBGrid1 к DataSource1, и DataSource1 к Table1. Затем установите свойства таблицы:

      • в DatabaseName имя подкаталога, где находятся демонстрационные таблицы (или псевдоним DBDEMOS);
      • в TableName установите имя таблицы CUSTOMER.

      Если Вы запустили программу, которая содержит видимый элемент TDBGrid, то увидите, что можно перемещаться по записям таблицы с помощью полос прокрутки (scrollbar) на нижней и правой сторонах DBGrid.

      Однако, иногда нужно перемещаться по таблице “программным путем”, без использования возможностей, встроенных в визуальные компоненты. В следующих нескольких абзацах объясняется как можно это сделать.

      Поместите две кнопки на форму и назовите их Next и Prior, как показано на рис.2.

      Дважды щелкните на кнопке Next — появится заготовка обработчика события:

      procedure TForm1.NextClick(Sender: TObject);

      Теперь добавьте a одну строчку кода так, чтобы процедура выглядела так:

      procedure TForm1.NextClick(Sender: TObject);

      Повторите те же самые действия с кнопкой Prior, так, чтобы функция связанная с ней выглядела так:

      procedure TForm1.PriorClick(Sender: TObject);

      Теперь запустите программу, и нажмите на кнопки. Вы увидите, что они легко позволяют Вам перемещаться по записям в таблице.

      Теперь добавьте еще две кнопки и назовите их First и Last, как показано на рис.3

      Рис .3: Программа со всеми четырьмя кнопками.

      Сделайте то же самое для новых кнопок.

      procedure TForm1.FirstClick(Sender: TObject);

      procedure TForm1.LastClick(Sender: TObject);

      Нет ничего более простого чем эти навигационные функции. First перемещает Вас в начало таблицы, Last перемещает Вас в конец таблицы, а Next и Prior перемещают Вас на одну запись вперед или назад.

      TDataSet.BOF — read-only Boolean свойство, используется для проверки, находитесь ли Вы в начале таблицы. Свойства BOF возвращает true в трех случаях:

      • После того, как Вы открыли файл;
      • После того, как Вы вызывали TDataSet.First;
      • После того, как вызов TDataSet.Prior не выполняется.

      Первые два пункта — очевидны. Когда Вы открываете таблицу, Delphi помещает Вас на первую запись; когда Вы вызываете метод First, Delphi также перемещает Вас в начало таблицы. Третий пункт, однако, требует небольшого пояснения: после того, как Вы вызывали метод Prior много раз, Вы могли добраться до начала таблицы, и следующий вызов Prior будет неудачным — после этого BOF и будет возвращать True.

      Следующий код показывает самый общий пример использования Prior, когда Вы попадаете к началу a файла:

      while not Table.Bof do begin

      В коде, показанном здесь, гипотетическая функция DoSomething будет вызвана сперва на текущей записи и затем на каждой следующей записи (от текущей и до начала таблицы). Цикл будет продолжаться до тех пор, пока вызов Table1.Prior не сможет больше переместить Вас на предыдущую запись в таблице. В этот момент BOF вернет True и программа выйдет из цикла. (Чтобы оптимизировать вышеприведенный код, установите DataSource1.Enabled в False перед началом цикла, и верните его в True после окончания цикла.)

      Все сказанное относительно BOF также применимо и к EOF. Другими словами, код, приведенный ниже показывает простой способ пробежать по всем записям в a dataset:

      while not Table1.EOF do begin

      Классическая ошибка в случаях, подобных этому: Вы входите в цикл while или repeat, но забываете вызывать Table1.Next:

      Если Вы случайно написали такой код, то ваша машина зависнет, и Вы сможете выйти из цикла только нажав Ctrl-Alt-Del и прервав текущий процесс. Также, этот код мог бы вызвать проблемы, если Вы открыли пустую таблицу. Так как здесь используется цикл repeat , DoSomething был бы вызван один раз, даже если бы нечего было обрабатывать. Поэтому, лучше использовать цикл while вместо repeat в ситуациях подобных этой.

      EOF возвращает True в следующих трех случаях:


      • После того, как Вы открыли пустой файл;
      • После того, как Вы вызывали TDataSet.Last;
      • После того, как вызов TDataSet.Next не выполняется.

      Единственная навигационная процедура, которая еще не упоминалась — MoveBy, которая позволяет Вам переместиться на N записей вперед или назад в таблице. Если Вы хотите переместиться на две записи вперед, то напишите:

      И если Вы хотите переместиться на две записи назад, то:

      При использовании этой функции Вы должны всегда помнить, что DataSet — это изменяющиеся объекты, и запись, которая была пятой по счету в предыдущий момент, теперь может быть четвертой или шестой или вообще может быть удалена.

      Prior и Next — это простые функции, которые вызывают MoveBy.

          1. Поля
          2. В большинстве случаев, когда Вы хотите получить доступ из программы к индивидуальные полям записи, Вы можете использовать одно из следующих свойств или методов, каждый из которых принадлежат TDataSet:

          property Fields[Index: Integer];

          function FieldByName(const FieldName: string): TField;

          Свойство FieldCount возвращает число полей в текущей структуре записи. Если Вы хотите программным путем прочитать имена полей, то используйте свойство Fields для доступа к ним:

          Если Вы работали с записью в которой первое поле называется CustNo, тогда код показанный выше поместит строку “CustNo” в переменную S. Если Вы хотите получить доступ к имени второго поля в вышеупомянутом примере, тогда Вы могли бы написать:

          Короче говоря, индекс передаваемый в Fields (начинающийся с нуля), и определяет номер поля к которому Вы получите доступ, т.е. первое поле — ноль, второе один, и так далее.

          Если Вы хотите прочитать текущее содержание конкретного поля конкретной записи, то Вы можете использовать свойство Fields или метод FieldsByName . Для того, чтобы найти значение первого поля записи, прочитайте первый элемент массива Fields:

          Предположим, что первое поле в записи содержит номер заказчика, тогда код, показанный выше, возвратил бы строку типа “1021”, “1031” или “2058”. Если Вы хотели получить доступ к этот переменный, как к числовой величине, тогда Вы могли бы использовать AsInteger вместо AsString. Аналогично, свойство Fields включают AsBoolean, AsFloat и AsDate.

          Если хотите, Вы можете использовать функцию FieldsByName вместо свойства Fields:

          Как показано в примерах выше, и FieldsByName, и Fields возвращают те же самые данные. Два различных синтаксиса используются исключительно для того, чтобы обеспечить программистов гибким и удобным набором инструментов для программного доступа к содержимому DataSet.

          Давайте посмотрим на простом примере, как можно использовать доступ к полям таблицы во время выполнения программы. Создайте новый проект, положите на форму объект TTable, два объекта ListBox и две кнопки — “Fields” и “Values” (см рис.4).

          Соедините объект TTable с таблицей CUSTOMER, которая поставляется вместе с Delphi (DBDEMOS), не забудьте открыть таблицу (Active = True).

          Рис .4: Программа FLDS показывает, как использовать свойство Fields.

          Сделайте Double click на кнопке Fields и создайте a метод который выглядит так:

          procedure TForm1.FieldsClick(Sender: TObject);

          for i := 0 to Table1.FieldCount — 1 do

          Обработчик события начинается с очистки первого ListBox1, затем он проходит через все поля, добавляя их имена один за другим в ListBox1. Заметьте, что цикл показанный здесь пробегает от 0 до FieldCount — 1. Если Вы забудете вычесть единицу из FieldCount, то Вы получите ошибку “List Index Out of Bounds”, так как Вы будете пытаться прочесть имя поля которое не существует.

          Предположим, что Вы ввели код правильно, и заполнили ListBox1 именами всех полей в текущей структуре записи.

          В Delphi существуют и другие средства которые позволяют Вам получить ту же самую информацию, но это самый простой способ доступа к именам полей в Run Time.

          Свойство Fields позволяет Вам получить доступ не только именам полей записи, но также и к содержимому полей. В нашем примере, для второй кнопки напишем:

          procedure TForm1.ValuesClick(Sender: TObject);

          for i := 0 to Table1.FieldCount — 1 do

          Этот код добавляет содержимое каждого из полей во второй listbox. Обратите внимание, что вновь счетчик изменяется от нуля до FieldCount — 1.

          Свойство Fields позволяет Вам выбрать тип результата написав Fields[N].AsString. Этот и несколько связанных методов обеспечивают a простой и гибкий способ доступа к данным, связанными с конкретным полем. Вот список доступных методов который Вы можете найти в описании класса TField:

          Всякий раз (когда это имеет смысл), Delphi сможет сделать преобразования. Например, Delphi может преобразовывать поле Boolean к Integer или Float, или поле Integer к String. Но не будет преобразовывать String к Integer, хотя и может преобразовывать Float к Integer. BLOB и Memo поля — специальные случаи, и мы их рассмотрим позже. Если Вы хотите работать с полями Date или DateTime, то можете использовать AsString и AsFloat для доступа к ним.

          Как было объяснено выше, свойство FieldByName позволяет Вам получить доступ к содержимому определенного поля просто указав имя этого поля:

          Это — удобная технология, которая имеет несколько преимуществ, когда используется соответствующим образом. Например, если Вы не уверены в местонахождении поля, или если Вы думаете, что структура записи, с которой Вы работаете могла измениться, и следовательно, местонахождение поля не определено.

        1. Работа с Данными
        2. Следующие методы позволяют Вам изменить данные, связанные с TTable:

          Все эти методы — часть TDataSet, они унаследованы и используются TTable и TQuery.

          Всякий раз, когда Вы хотите изменить данные, Вы должны сначала перевести DataSet в режим редактирования. Как Вы увидите, большинство визуальных компонент делают это автоматически, и когда Вы используете их, то совершенно не будете об этом заботиться. Однако, если Вы хотите изменить TTable программно, Вам придется использовать вышеупомянутые функции.

          Имеется a типичная последовательность, которую Вы могли бы использовать при изменении поля текущей записи:

          Первая строка переводит БД в режим редактирования. Следующая строка присваивает значение ‘Fred’ полю ‘CustName’. Наконец, данные записываются на диск, когда Вы вызываете Post.

          При использовании такого подхода, Вы всегда работаете с записями. Сам факт перемещения к следующей записи автоматически сохраняет ваши данные на диск. Например, следующий код будет иметь тот же самый эффект, что и код показанный выше, плюс этому будет перемещать Вас на следующую запись:

          Общее правило, которому нужно следовать — всякий раз, когда Вы сдвигаетесь с текущей записи, введенные Вами данные будут записаны автоматически. Это означает, что вызовы First, Next, Prior и Last всегда выполняют Post , если Вы находились в режиме редактирования. Если Вы работаете с данными на сервере и транзакциями, тогда правила, приведенные здесь, не применяются. Однако, транзакции — это отдельный вопрос с их собственными специальными правилами, Вы увидите это, когда прочитаете о них в следующих уроках.

          Тем не менее, даже если Вы не работаете со транзакциями, Вы можете все же отменить результаты вашего редактирования в любое время, до тех пор, пока не вызвали напрямую или косвенно метод Post . Например, если Вы перевели таблицу в режим редактирования, и изменили данные в одном или более полей, Вы можете всегда вернуть запись в исходное состояние вызовом метода Cancel.

          Существуют два метода, названные Append и Insert , который Вы можете использовать всякий раз, когда Вы хотите добавить новую запись в DataSet. Очевидно имеет больше смысла использовать Append для DataSets которые не индексированы, но Delphi не будет генерировать exception если Вы используете Append на индексированной таблице. Фактически, всегда можно использовать и Append , и Insert.

          Продемонстрируем работу методов на простом примере. Чтобы создать программу, используйте TTable, TDataSource и TdbGrid. Открыть таблицу COUNTRY. Затем разместите две кнопки на форме и назовите их ‘Insert’ и ‘Delete’. Когда Вы все сделаете, то должна получиться программа, показанная на рис.5

          Рис .5: Программа может вставлять и удалять запись из таблицы COUNTRY.

          Следующим шагом Вы должен связать код с кнопками Insert и Delete:

          procedure TForm1.InsertClick(Sender: TObject);

          procedure TForm1.DeleteClick(Sender: TObject);

          Процедура показанная здесь сначала переводит таблицу в режим вставки (новая запись с незаполненными полями вставляется в текущую позицию dataset). После вставки пустой записи, следующим этапом нужно назначить значения одному или большему количеству полей. Существует, конечно, несколько различных путей присвоить эти значения. В нашей программе Вы могли бы просто ввести информацию в новую запись через DBGrid. Или Вы могли бы разместить на форме стандартную строку ввода (TEdit) и затем установить каждое поле равным значению, которое пользователь напечатал в этой строке:

          Можно было бы использовать компоненты, специально предназначенные для работы с данными в DataSet.

          Назначение этой главы, однако, состоит в том, чтобы показать, как вводить данные из программы. Поэтому, в примере вводимая информация скомпилирована прямо в код программы:

          Один из интересных моментов в этом примере это то, что нажатие кнопки Insert дважды подряд автоматически вызывает exception ‘Key Violation’. Чтобы исправить эту ситуацию, Вы должны либо удалить текущую запись, или изменять поля Name и Capital вновь созданной записи.

          Просматривая код показанный выше, Вы увидите, что просто вставка записи и заполнения ее полей не достаточно для того, чтобы изменить физические данные на диске. Если Вы хотите, чтобы информация записалась на диск, Вы должны вызывать Post.

          Если после вызова Insert, Вы решаете отказаться от вставки новой записи, то Вы можете вызвать Cancel. Если Вы сделаете это прежде, чем Вы вызовете Post, то все что Вы ввели после вызова Insert будет отменено, и dataset будет находиться в состоянии, которое было до вызова Insert.

          Одно дополнительное свойство, которое Вы должны иметь в виду называется CanModify . Если CanModify возвращает False, то TTable находиться в состоянии ReadOnly. В противном случае CanModify возвращает True и Вы можете редактировать или добавлять записи в нее по желанию. CanModify — само по себе ‘read only’ свойство. Если Вы хотите установить DataSet в состояние только на чтение (Read Only), то Вы должны использовать свойство ReadOnly , не CanModify.

        3. Использование SetKey для поиска в таблице
        4. Для того, чтобы найти некоторую величину в таблице, программист на Delphi может использовать две процедуры SetKey и GotoKey . Обе эти процедуры предполагают, что поле по которому Вы ищете индексировано. Delphi поставляется с демонстрационной программой SEARCH, которая показывает, как использовать эти запросы.

          Чтобы создать программу SEARCH, поместите TTable, TDataSource, TDBGrid, TButton, TLabel и TEdit на форму, и расположите их как показано на рис.6. Назовите кнопку Search, и затем соедините компоненты БД так, чтобы Вы видели в DBGrid1 таблицу Customer.

          Рис .6: Программа SEARCH позволяет Вам ввести номер заказчика и затем найти его по нажатию кнопки.

          Вся функциональность программы SEARCH скрыта в единственном методе, который присоединен к кнопке Search. Эта функция считывает строку, введенную в окно редактора, и ищет ее в колонке CustNo, и наконец помещает фокус на найденной записи. В простейшем варианте, код присоединенный к кнопке Search выглядит так:

          procedure TSearchDemo.SearchClick(Sender: TObject);

          Первый вызов в этой процедуре установит Table1 в режим поиска. Delphi должен знать, что Вы переключились в режим поиска просто потому, что свойство Fields используется по другому в этом режиме. Далее, нужно присвоить свойству Fields значение, которое Вы хотите найти. Для фактического выполнения поиска нужно просто вызывать Table1.GotoKey.

          Если Вы ищете не по первичному индексу файла, тогда Вы должны определить имя индекса, который Вы используете в свойстве IndexName. Например, если таблица Customer имеет вторичный индекс по полю City, тогда Вы должны установить свойство IndexName равным имени индекса. Когда Вы будете искать по этому полю, Вы должны написать:

          Запомните: поиск не будет выполняться, если Вы не назначите правильно индекс (св-во IndexName). Кроме того, Вы должны обратить внимание, что IndexName — это свойство TTable, и не присутствует в других прямых потомках TDataSet или TDBDataSet.

          Когда Вы ищете некоторое значение в БД, всегда существует вероятность того, что поиск окажется неудачным. В таком случае Delphi будет автоматически вызывать exception, но если Вы хотите обработать ошибку сами, то могли бы написать примерно такой код:

          procedure TSearchDemo.SearchClick(Sender: TObject);

          if not Cust.GotoKey then

          raise Exception.CreateFmt(‘Cannot find CustNo %g’,

          В коде, показанном выше, либо неверное присвоение номера, либо неудача поиска автоматически приведут к сообщению об ошибке ‘ Cannot find CustNo %g ’.

          Иногда требуется найти не точно совпадающее значение, а близкое к нему, для этого следует вместо GotoKey пользоваться методом GotoNearest.

        5. Использование фильтров для ограничения числа записей в DataSet

    Процедура ApplyRange позволяет Вам установить фильтр, который ограничивает диапазон просматриваемых записей. Например, в БД Customers, поле CustNo имеет диапазон от 1,000 до 10,000. Если Вы хотите видеть только те записи, которые имеют номер заказчика между 2000 и 3000, то Вы должны использовать метод ApplyRange , и еще два связанных с ним метода. Данные методы работают только с индексированным полем.

    Вот процедуры, которые Вы будете чаще всего использовать при установке фильтров:

    Кроме того, у TTable есть дополнительные методы для управления фильтрами:

    Для использования этих процедур необходимо:

    1. Сначала вызвать SetRangeStart и использовать свойство Fields для определения начала диапазона.
    2. Затем вызвать SetRangeEnd и вновь использовать свойство Fields для определения конца диапазона.
    3. Первые два шага подготавливают фильтр, и теперь все что Вам необходимо, это вызвать ApplyRange , и новый фильтр вступит в силу.
    4. Когда нужно прекратить действие фильтра — вызовите CancelRange.

    Программа RANGE, которая есть среди примеров Delphi, показывает, как использовать эти процедуры. Чтобы создать программу, поместите TTable, TDataSource и TdbGrid на форму. Соедините их так, чтобы Вы видеть таблицу CUSTOMERS из подкаталога DEMOS. Затем поместите два объекта TLabel на форму и назовите их ‘Start Range’ и ‘End Range’. Затем положите на форму два объекта TEdit. Наконец, добавьте кнопки ‘ApplyRange’ и ‘CancelRange’. Когда Вы все выполните, форма имеет вид, как на рис.7

    Рис .7: Программа RANGE показывает как ограничивать число записей таблицы для просмотра.

    Процедуры SetRangeStart и SetRangeEnd позволяют Вам указать первое и последнее значения в диапазоне записей, которые Вы хотите видеть. Чтобы начать использовать эти процедуры, сначала выполните double-click на кнопке ApplyRange , и создайте процедуру, которая выглядит так:

    procedure TForm1.ApplyRangeBtnClick(Sender: TObject);

    if RangeStart.Text <> » then

    Table1. Fields[0].AsString := RangeStart.Text;

    if RangeEnd.Text <> » then

    Сначала вызывается процедура SetRangeStart , которая переводит таблицу в режим диапазона (range mode). Затем Вы должны определить начало и конец диапазона. Обратите внимание, что Вы используете свойство Fields для определения диапазона:

    Такое использование свойства Fields — это специальный случай, так как синтаксис, показанный здесь, обычно используется для установки значения поля. Этот специальный случай имеет место только после того, как Вы перевели таблицу в режим диапазона, вызвав SetRangeStart.

    Заключительный шаг в процедуре показанной выше — вызов ApplyRange . Этот вызов фактически приводит ваш запрос в действие. После вызова ApplyRange, TTable больше не в находится в режиме диапазона, и свойства Fields функционирует как обычно.

    Обработчик события нажатия кнопки ‘CancelRange’:

    procedure TForm1.CancelRangeBtnClick(Sender: TObject);

        1. Обновление (Refresh)
        2. Как Вы уже знаете, любая таблица, которую Вы открываете всегда “подвержена изменению”. Короче говоря, Вы должны расценить таблицу скорее как меняющуюся, чем как статическую сущность. Даже если Вы — единственное лицо, использующее данную TTable, и даже если Вы не работаете в сети, всегда существует возможность того, что программа с которой Вы работаете, может иметь два различных пути изменения данных в таблице. В результате, Вы должны всегда знать, необходимо ли Вам обновить вид таблицы на экране.

        Функция Refresh связана с функцией Open , в том смысле что она считывает данные, или некоторую часть данных, связанных с данной таблицей. Например, когда Вы открываете таблицу, Delphi считывает данные непосредственно из файла БД. Аналогично, когда Вы Регенерируете таблицу, Delphi считывает данные напрямую из таблицы. Поэтому Вы можете использовать эту функцию, чтобы перепрочитать таблицу, если Вы думаете что она могла измениться. Быстрее и эффективнее, вызывать Refresh , чем вызывать Close и затем Open.

        Имейте ввиду, однако, что обновление TTable может иногда привести к неожиданным результатам. Например, если a пользователь рассматривает запись, которая уже была удалена, то она исчезнет с экрана в тот момент, когда будет вызван Refresh. Аналогично, если некий другой пользователь редактировал данные, то вызов Refresh приведет к динамическому изменению данных. Конечно маловероятно, что один пользователь будет изменять или удалять запись в то время, как другой просматривает ее, но это возможно.

      1. Закладки (Bookmarks)
      2. Часто бывает полезно отметить текущее местоположение в таблице так, чтобы можно было быстро возвратиться к этому месту в дальнейшем. Delphi обеспечивает эту функциональную возможность посредством трех методов, которые используют понятие закладки .

        function GetBookmark: TBookmark;

        (устанавливает закладку в таблице)

        procedure GotoBookmark(Bookmark: TBookmark);

        (переходит на закладку)

        procedure FreeBookmark(Bookmark: TBookmark);

        Как Вы можете видеть, вызов GetBookmark возвращает переменную типа TBookmark. TBookmark содержит достаточное количество информации, чтобы Delphi мог найти местоположение к которому относится этот TBookmark. Поэтому Вы можете просто передавать этот TBookmark функции GotoBookmark, и будете немедленно возвращены к местоположению, связанному с этой закладкой.

        Обратите внимание, что вызов GetBookmark распределяет память для TBookmark, так что Вы должны вызывать FreeBookmark до окончания вашей программы, и перед каждой попыткой повторного использования Tbookmark (в GetBookMark).

        Связанные курсоры позволяют программистам определить отношение один ко многим (one-to-many relationship). Например, иногда полезно связать таблицы CUSTOMER и ORDERS так, чтобы каждый раз, когда пользователь выбирает имя заказчика, то он видит список заказов связанных с этим заказчиком. Иначе говоря, когда пользователь выбирает запись о заказчике, то он может просматривать только заказы, сделанные этим заказчиком.

        Программа LINKTBL демонстрирует, как создать программу которая использует связанные курсоры. Чтобы создать программу заново, поместите два TTable, два TDataSources и два TDBGrid на форму. Присоедините первый набор таблице CUSTOMER, а второй к таблице ORDERS. Программа в этой стадии имеет вид, показанный на рис.8

        Следующий шаг должен связать таблицу ORDERS с таблицей CUSTOMER так, чтобы Вы видели только те заказы, которые связанные с текущей записью в таблице заказчиков. В первой таблице заказчик однозначно идентифицируется своим номером — поле CustNo. Во второй таблице принадлежность заказа определяется также номером заказчика в поле CustNo. Следовательно, таблицы нужно связывать по полю CustNo в обоих таблицах (поля могут иметь различное название, но должны быть совместимы по типу). Для этого, Вы должны сделать три шага, каждый из которых требует некоторого пояснения:

        1. Установить свойство Table2.MasterSource = DataSource1
        2. Установить свойство Table2.MasterField = CustNo
        3. Установить свойство Table2.IndexName = CustNo

        Если Вы теперь запустите программу, то увидите, что обе таблицы связаны вместе, и всякий раз, когда Вы перемещаетесь на новую запись в таблице CUSTOMER, Вы будете видеть только те записи в таблице ORDERS, которые принадлежат этому заказчику.

        Свойство MasterSource в Table2 определяет DataSource от которого Table2 может получить информацию. То есть, оно позволяет таблице ORDERS знать, какая запись в настоящее время является текущей в таблице CUSTOMERS.

        Но тогда возникает вопрос: Какая еще информация нужна Table2 для того, чтобы должным образом отфильтровать содержимое таблицы ORDERS? Ответ состоит из двух частей:

        1. Требуется имя поля по которому связанны две таблицы.
        2. Требуется индекс по этому полю в таблице ORDERS (в таблице ‘многих записей’), которая будет связываться с таблицей CUSTOMER(таблице в которой выбирается ‘одна запись’).

        Чтобы правильно воспользоваться информацией описанной здесь, Вы должны сначала проверить, что таблица ORDERS имеет нужные индексы. Если этот индекс первичный, тогда не нужно дополнительно указывать его в поле IndexName, и поэтому Вы можете оставить это поле незаполненным в таблице TTable2 (ORDERS). Однако, если таблица связана с другой через вторичный индекс, то Вы должны явно определять этот индекс в поле IndexName связанной таблицы.

        В примере показанном здесь таблица ORDERS не имеет первичного индекса по полю CustNo, так что Вы должны явно задать в свойстве IndexName индекс CustNo.

        Недостаточно, однако, просто yпомянуть имя индекса, который Вы хотите использовать. Некоторые индексы могут содержать несколько полей, так что Вы должны явно задать имя поля, по которому Вы хотите связать две таблицы. Вы должны ввести имя ‘CustNo’ в свойство Table2.MasterFields. Если Вы хотите связать две таблицы больше чем по одному полю, Вы должны внести в список все поля, помещая символ ‘|’ между каждым:

        Table1.MasterFields := ‘CustNo | SaleData | ShipDate’;

        В данном конкретном случае, выражение, показанное здесь, не имеет смысла, так как хотя поля SaleData и ShipDate также индексированы, но не дублируются в таблице CUSTOMER. Поэтому Вы должны ввести только поле CustNo в свойстве MasterFields. Вы можете определить это непосредственно в редакторе свойств, или написать код подобно показанному выше. Кроме того, поле (или поля) связи можно получить, вызвав редактор связей — в Инспекторе Объектов дважды щелкните на свойство MasterFields (рис.10)

        Рис.10: Редактор связей для построения связанных курсоров.

        Важно подчеркнуть, что данная глава охватила только один из нескольких путей, которым Вы можете создать связанные курсоры в Delphi. В главе о запросах будет описан второй метод, который будет обращен к тем кто знаком с SQL.

            1. Основные понятия о TDataSource
            2. Класс TDataSource используется в качестве проводника между TTable или TQuery и компонентами, визуализирующими данные, типа TDBGrid, TDBEdit и TDBComboBox (data-aware components). В большинстве случаев, все, что нужно сделать с DataSource — это указать в свойстве DataSet соответствующий TTable или TQuery. Затем, у data-aware компонента в свойстве DataSource указывается TDataSource, который используется в настоящее время.

            TDataSource также имеет свойство Enabled, и оно может быть полезно всякий раз, когда Вы хотите временно отсоединить, например, DBGrid от таблицы или запроса. Эти требуется, например, если нужно программно пройти через все записи в таблице. Ведь, если таблица связана с визуальными компонентами (DBGrid, DBEdit и т.п.), то каждый раз, когда Вы вызываете метод TTable.Next, визуальные компоненты будут перерисовываться. Даже если само сканирование в таблице двух или трех тысяч записей не займет много времени, то может потребоваться значительно больше времени, чтобы столько же раз перерисовать визуальные компоненты. В случаях подобных этому, лучше всего установить поле DataSource.Eabled в False. Это позволит Вам просканировать записи без перерисовки визуальных компонент. Это единственная операция может увеличить скорость в некоторых случаях на несколько тысяч процентов.

            Свойство TDataSource.AutoEdit указывает, переходит ли DataSet автоматически в режим редактирования при вводе текста в data-aware объекте.

          1. Использование TDataSource для проверки состояния БД:
          2. TDataSource имеет три ключевых события, связанных с состоянием БД

            OnDataChange происходит всякий раз, когда Вы переходите на новую запись, или состояние DataSet сменилось с dsInactive на другое, или начато редактирование. Другими словами, если Вы вызываете Next, Previous, Insert, или любой другой запрос, который должен привести к изменению данных, связанных с текущей записью, то произойдет событие OnDataChange. Если в программе нужно определить момент, когда происходит переход на другую запись, то это можно сделать в обработчике события OnDataChange:

            procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);

            if DataSource1.DataSet.State = dsBrowse then begin

            Событие OnStateChange событие происходит всякий раз, когда изменяется текущее состояние DataSet. DataSet всегда знает, в каком состоянии он находится. Если Вы вызываете Edit, Append или Insert, то TTable знает, что он теперь находится в режиме редактирования (dsEdit или dsInsert). Аналогично, после того, как Вы делаете Post, то TTable знает что данные больше не редактируется, и переключается обратно в режим просмотра (dsBrowse).

            Dataset имеет шесть различных возможных состояний, каждое из которых включено в следующем перечисляемом типе:

            TDataSetState = (dsInactive, dsBrowse, dsEdit, dsInsert,

            В течение обычного сеанса работы, БД часто меняет свое состояние между Browse, Edit, Insert и другими режимами. Если Вы хотите отслеживать эти изменения, то Вы можете реагировать на них написав примерно такой код:

            procedure TForm1.DataSource1StateChange(Sender: TObject);


            case Table1.State of

            dsInactive: S := ‘Inactive’;

            dsBrowse: S := ‘Browse’;

            dsInsert: S := ‘Insert’;

            dsSetKey: S := ‘SetKey’;

            dsCalcFields: S := ‘CalcFields’;

            OnUpdateData событие происходит перед тем, как данные в текущей записи будут обновлены. Например, OnUpdateEvent будет происходить между вызовом Post и фактическим обновлением информации на диске.

            События, генерируемые TDataSource могут быть очень полезны. Иллюстрацией этого служит следующий пример. Эта программа работает с таблицей COUNTRY, и включает TTable, TDataSource, пять TEdit, шесть TLlabel, восемь кнопок и панель. Действительное расположение элементов показано на рис.11. Обратите внимание, что шестой TLabel расположен на панели внизу главной формы.

            Рис .11: Программа STATE показывает, как отслеживать текущее состояние таблицы.

            Для всех кнопок напишите обработчики, вроде:

            procedure TForm1.FirstClick(Sender: TObject);

            В данной программе есть одна маленькая хитрость, которую Вы должны понять, если хотите узнать, как работает программа. Так как есть пять отдельных редакторов TEdit на главной форме, то хотелось бы иметь некоторый способ обращаться к ним быстро и легко. Один простой способ состоит в том, чтобы объявить массив редакторов:

            Edits: array[1..5] of TEdit;

            Чтобы заполнить массив, Вы можете в событии OnCreate главной формы написать:

            procedure TForm1.FormCreate(Sender: TObject);

            for i := 1 to 5 do

            Edits[i] := TEdit(FindComponent(‘Edit’ + IntToStr(i)));

            Код показанный здесь предполагает, что первый редактор, который Вы будете использовать назовем Edit1, второй Edit2, и т.д. Существование этого массива позволяет очень просто использовать событие OnDataChange, чтобы синхронизировать содержание объектов TEdit с содержимом текущей записи в DataSet:

            procedure TForm1.DataSource1DataChange(Sender: TObject;

            for i := 1 to 5 do

            Edits[i].Text := Table1.Fields[i — 1].AsString;

            Всякий раз, когда вызывается Table1.Next, или любой другой из навигационных методов, то будет вызвана процедура показанная выше. Это обеспечивает то, что все редакторы всегда содержат данные из текущей записи.

            Всякий раз, когда вызывается Post, нужно выполнить противоположное действие, то есть взять информацию из редакторов и поместить ее в текущую запись. Выполнить это действие, проще всего в обработчике события TDataSource.OnUpdateData, которое происходит всякий раз, когда вызывается Post:

            procedure TForm1.DataSource1UpdateData(Sender: TObject);

            for i := 1 to 5 do

            Table1.Fields[i — 1].AsString := Edits[i].Text;

            Программа будет автоматически переключатся в режим редактирования каждый раз, когда Вы вводите что-либо в одном из редакторов. Это делается в обработчике события OnKeyDown (укажите этот обработчик ко всем редакторам):

            procedure TForm1.Edit1KeyDown(Sender: TObject;

            var Key: Word; Shift: TShiftState);

            if DataSource1.State <> dsEdit then

            Этот код показывает, как Вы можете использовать св-во State DataSource, чтобы определить текущий режим DataSet.

            Обновление метки в статусной панели происходит при изменении состояния таблицы:

            procedure TForm1.DataSource1StateChange(Sender: TObject);

            case DataSource1.State of

            Данная программа является демонстрационной и ту же задачу можно решить гораздо проще, если использовать объекты TDBEdit.

            В предыдущей части Вы узнали, как использовать TDataSource, чтобы узнать текущее состоянии TDataSet. Использование DataSource — это простой путь выполнения данной задачи. Однако, если Вы хотите отслеживать эти события без использования DataSource, то можете написать свои обработчики событий TTable и TQuery:

            Разница append и insert в ADO Delphi 7

            Организую добавление записей в таблицу следующим образом:

            В конец таблицы — методом Append:

            В текущую позицию — методом Insert:

            Поля Номер и Кол-во страниц — числовые, остальные — текстовые. Ключевое поле — Номер.

            Теперь проблема: Метод Insert почему-то добавляет запись в конец таблицы, хотя должен сдвигать записи и вставлять новую в текущую позицию.

            Работа со строками в Delphi 10.1 Berlin

            Автор: Alex. Опубликовано в Программирование 31 Январь 2020 . просмотров: 23138

            Для работы со строками в последних версиях Delphi разработчикам доступно большое количество функций, помимо которых ещё есть помощники для работы со строками, такие как TStringHelper, TStringBuilder и TRegEx. Во всём этом разнообразии бывает сложно найти нужную функцию. Я попытался разобраться, что есть в Delphi 10.1 Berlin для работы со строками и как этим всем пользоваться.

            Итак, прежде чем начнём разбираться с функциями, замечу, что начиная с Delphi XE3, появился помощник TStringHelper, и теперь работать со строками можно как с записями. Т.е., если вы определили переменную со строкой (на картинке снизу – это myStr), то вы можете поставить точку и посмотреть, какие функции доступны. Это очень удобно.

            Кстати аналогичные помощники появились и для работы с типами Single, Double и Extended: TSingleHelper, TDoubleHelper и TExtendedHelper.

            Ну и конечно, помимо помощника TStringHelper, никуда не делся класс TStringBuilder, который используется для работы со строкой как с массивом, и который является полностью совместимым с .NET классом StringBuilder.

            А для работы с текстовыми документами незаменимым окажется класс TRegEx, который является обёрткой над библиотекой PCRE, позволяющий использовать регулярные выражения для поиска, замены подстрок и расщепления текста на части.

            Все приведённые в статье примеры сделаны с помощью Delphi 10.1 Berlin, поэтому в других версиях Delphi их работа не гарантируется.

            Вот основные моменты, которые мы рассмотрим в статье:

            Строки в Delphi

            В последних версиях Delphi тип string, обозначающий строку, является псевдонимом встроенного типа System.UnicodeString. Т.е. когда вы объявляете переменную str: string, то автоматически вы объявляете переменную типа UnicodeString.

            Кстати, на платформе Win32 вы можете использовать директиву « », которая превратит тип string в ShortString. С помощью этого способа вы можете использовать старый 16-битный код Delphi или Turbo Pascal в ваших проектах.

            Обратите внимание, что кроме типа UnicodeString и ShortString в Delphi есть и другие типы строк, такие как AnsiString и WideString, однако дальше в статье мы будем рассматривать только работу со строками типа string.

            Более глубокое изучение строк в Delphi вы можете начать с прочтения документации здесь.

            Инициализация строк

            Конечно, начнём мы с инициализации строк. Итак, рассмотрим объявление переменной с типом string.

            В этой строчке кода мы объявляем переменную s с типом string, т.е., как было написано выше, по умолчанию с типом UnicodeString. Объявленные переменные с типом UnicodeString, в которые не присвоено значение, всегда гарантированно содержат строку нулевой длины. Чтобы теперь в переменной s была нужная нам строка, нужно просто присвоить переменной другое значение, например:

            Это самый простой и часто используемый способ инициализации. Кроме этого есть ряд полезных функций, которые пригодятся вам для инициализации строк в некоторых ситуациях (здесь и далее я буду давать полный код проекта консольного Win32 приложения):

            Изменение регистра

            Для изменения регистра строк в Delphi есть функции LowerCase, UpperCase, TStringHelper.ToLower, TStringHelper.ToUpper, TStringHelper.ToLowerInvariant и TStringHelper.ToUpperInvariant. В нижний регистр строки меняют функции LowerCase, TStringHelper.ToLower и TStringHelper.ToLowerInvariant, остальные – в верхний. Обратите внимание, что функции LowerCase и UpperCase не работают с кириллицей. Функции TStringHelper.ToUpperInvariant и TStringHelper.ToLowerInvariant всегда работают независимо от текущей пользовательской локали. Вот примеры использования функций:

            Конкатенация строк

            Здесь конечно самый простой вариант – это использование оператора +. Но есть и другие варианты, например, функция Concat. А если вам нужно в цикле добавлять в конец одной строки большое количество других строк, то здесь пригодится метод Append класса TStringBuilder. Вот пример использования перечисленных способов:

            Во всех четырёх переменных, после выполнения нашей программы, будет следующая строка: «Абвгдеёжзиклмнопрст». Четвёртый способ выглядит более громоздким, но у такого способа есть три преимущества. Во-первых, при большом количестве конкатенаций этот способ даст выигрыш по времени по сравнению с первыми тремя способами. Во-вторых, при создании объекта TStringBuilder вы сразу можете задать нужный размер массива для хранения строки, если он конечно известен. Это тоже даст выигрыш по времени. В-третьих, функция Append принимает на вход не только строки, но и другие типы, такие как Integer и Single, автоматически преобразуя их в строку.

            Третий способ удобно использовать, если нужно сложить строки, находящиеся в массиве или списке. К тому же здесь первым параметром можно задать строку-разделитель, которая будет вставлена между строками, взятыми из массива. Вот пример, в котором формируется строка со списком городов, разделённых запятыми:

            В результате выполнения этой функции получится строка «Москва, Санкт-Петербург, Севастополь».

            Вставка подстроки в строку

            Для того чтобы вставить внутрь строки подстроку вы можете использовать процедуру Insert или функцию TStringHelper.Insert. У класса TStringBuilder тоже есть аналогичная функция. Кстати, функция TStringBuilder.Insert, кроме строк умеет вставлять и другие типы, такие как Integer и Single, автоматически преобразуя их в строку. Вот пример использования:

            Обратите внимание, в процедуре Insert нумерация символов начинается с 1, а в функциях TStringHelper.Insert и TStringBuilder.Insert – с 0. Все приведённые способы меняют строку, хранящуюся в переменной.

            Удаление части строки

            Допустим, вам нужно удалить из строки часть символов. Здесь нам помогут процедура Delete и функция TStringHelper.Remove. У класса TStringBuilder тоже есть функция Remove. Вот примеры использования:

            Во всех трёх способах из строки «Абвгд» получится строка «Агд». Обратите внимание, что в процедуре Delete нумерация символов начинается с 1, а в функциях Remove – с 0.

            Также интересно, что функция TStringHelper.Remove не трогает исходную строку. Вместо этого она возвращает новую строку с удалёнными символами. Именно поэтому мы присваиваем результат обратно в переменную. Процедура Delete работает по-другому: она меняет исходную строку.

            Помимо приведённых здесь вариантов, для удаления части строки можно использовать функции замены подстроки, просто для этого искомая подстрока заменяется на пустую, например, StringReplace(str1, substr1, »).

            Копирование части строки

            Здесь идёт речь о том, что часть длиной строки нужно скопировать в новую строку или массив символов. Для этого в Delphi есть функции LeftStr, RightStr, Copy, TStringHelper.Substring и TStringHelper.CopyTo. А в классе TStringBuilder – только функция CopyTo. Есть также функция MidStr в юните System.StrUtils, которая работает аналогично функции Copy, поэтому в примере её не будет.

            Первые два способа копируют часть строки слева (функция LeftStr) или справа (RightStr). Остальные четыре способа подходят, как для копирования части строки слева или справа, так и из середины.

            В способах 3-6 из примера мы получим сроку «вгд» или массив [‘в’, ‘г’, ‘д’]. Обратите внимание, что в функциях Copy и MidStr нумерация символов начинается с 1, а во всех остальных с 0. Исходная строка или массив символов во всех четырёх способах не меняется.

            Сравнение строк

            Конечно, сравнивать строки можно с помощью операторов =, , >= и <>. Но кроме этого существуют ещё много функций: StrComp, StrIComp, StrLComp, StrLIComp, CompareStr, CompareText, TStringHelper.Compare, TStringHelper.CompareOrdinal, TStringHelper.CompareTo, TStringHelper.CompareText, SameStr, SameText, TStringHelper.Equals и TStringBuilder.Equals. Функции SameText, StrIComp, CompareText, TStringHelper.CompareText и TStringHelper.Compare умеют производить регистронезависимое сравнение строк, остальные функции и операторы — регистрозависимое.

            Третьим параметром в функциях CompareText и SameText можно указать, что нужно использовать для сравнения строк пользовательскую локаль. В этом случае вы сможете сравнивать строки с русскими буквами независимо от регистра, если конечно в ОС используется русский язык.

            Самая продвинутая здесь функция – это TStringHelper.Compare. С помощью неё можно сравнивать не только целые строки, но и части строк. Здесь можно настроить зависимость от регистра, включить игнорирование символов и знаков препинания или сравнение цифр как чисел и т.д.

            Операторы, а также функции TStringHelper.Equals и TStringBuilder.Equals, в результате сравнения, отдадут вам True, если условие верно, и False, если условие не верно. Функции CompareStr, CompareText, TStringHelper.Compare, TStringHelper.CompareTo, TStringHelper.CompareOrdinal и TStringHelper.CompareText работают по-другому. Они сравнивают строки с точки зрения сортировки. Функции возвращают отрицательное число, если строка, указанная в первом параметре, сортируется до строки, указанной во втором параметре, положительное число — если первая строка сортируется после второй и 0 – если строки равны.

            Функции SameStr, SameText, TStringHelper.Equals и TStringBuilder.Equals сравнивают строки на соответствие.

            Итак, вот примеры использования вышеперечисленных функций и операторов:

            Поиск подстроки в строке

            Теперь давайте посмотрим, как можно найти подстроку (определённую последовательность символов) в строке. Здесь у вас есть большой выбор функций, которые возвращают либо индекс найденной подстроки, либо true или false в зависимости от того, найдена подстрока в строке или нет. Итак, давайте перечислим все функции для поиска подстроки:

            В первую очередь – это функция Pos, которая ищет подстроку, начиная с указанного номера символа. Функция осуществляет регистрозависимый поиск. Здесь нумерация символов начинается с 1. Если подстрока найдена, то возвращается номер первого символа найденной подстроки, иначе – 0. Есть также функция PosEx (в юните System.StrUtils), которая работает абсолютно также. Вот пример использования функции Pos:

            Аналогично функции Pos работают и функции IndexOf и LastIndexOf помощника TStringHelper. Они также осуществляют регистрозависимый поиск. Функция IndexOf ищет подстроку (или символ) с начала и до конца строки, а функция LasIndexOf – наоборот, т.е. с конца и до начала. Если подстрока найдена, то функции возвращают индекс первого символа найденной подстроки в строке. Здесь нумерация символов начинается с 0. Если подстрока не найдена, то функции возвращают -1. Также при поиске вы можете задать начало и интервал поиска. Вот примеры использования этих функций:

            Теперь рассмотрим функции для проверки, есть ли подстрока в строке, и не важно, в каком месте. Для этого есть функции ContainsStr и ContainsText в юните System.StrUtils, а также функция Contains в помощнике TStringHelper.Contains. Функции ContainsStr и TStringHelper.Contains – регистрозависимые, а функция ContainsText – нет. Вот примеры использования этих функций:

            Дополнительно есть функции проверяющие, наличие определённой подстроки в начале или в конце текста. Это функции StartsStr, StartsText, EndsStr и EndsText в юните System.StrUtils, а также функции StartsWith, EndsWith и EndsText у помощника TStringHelper. Функции StartsStr и EndsStr регистрозависимые, функции StartsText, EndsText и TStringHelper.EndsText регистронезависимые, а у функций TStringHelper.StartsWith и TStringHelper.EndsWith есть второй параметр для выбора режима поиска. Учтите, что регистронезависимый поиск в функции TStringHelper.StartsWith работает только с буквами латинского алфавита. По умолчанию поиск в функциях TStringHelper.StartsWith и TStringHelper.EndsWith регистрозависимый.

            Обратите внимание, что регистронезависимый поиск в функциях StartsText, EndsText и TStringHelper.EndsText и TStringHelper.EndsWith ведётся для текущей локали. Т.е. если на компьютере будет установлена английская локаль, то регистронезависимый поиск по русскому тексту работать не будет.

            Вот примеры использования функций:

            И конечно самые продвинутые условия для поиска подстрок можно задавать при помощи регулярных выражений. Для этого есть функции TRegEx.Match и TRegEx.Matches. Вот несколько примеров использования этих функций:

            Примеры и описание регулярных выражений смотрите на сайте библиотеки PCRE.

            Поиск символов в строке

            Случается, что нужно найти определённые символы в строке. Конечно, для этого вы можете воспользоваться функциями для поиска подстроки, о которых было написано выше, но есть и специальные функции, позволяющие найти первый попавшийся в строке символ из нескольких искомых. Это функции помощника TStringHelper: IndexOfAny, IndexOfAnyUnquoted и LastIndexOfAny. Функции IndexOfAny и IndexOfAnyUnquoted ищут, перебирая символы сначала до конца строки, а функция LastIndexOfAny – наоборот. Во всех функциях можно указать интервал поиска. Функция IndexOfAnyUnquoted умеет игнорировать символы, заключенные в кавычки, скобки и т.п. Вот пример использования этих функций:

            Замена подстроки в строке

            Для поиска и замены подстроки (или символа) в строке можно использовать функции StringReplace, ReplaceStr и ReplaceText, TStringHelper.Replace, TStringBuilder.Replace и TRegEx.Replace. Функции ReplaceStr и TStringBuilder.Replace – регистрозависимые, функция ReplaceText – регистронезависимая, в функциях StringReplace, TStringHelper.Replace и TRegEx.Replace зависимость от регистра настраивается флажком rfIgnoreCase. Функции TRegEx.Replace ищут подстроку, используя регулярные выражения. В функции TStringBuilder.Replace можно задать диапазон поиска подстроки. Вот примеры использования этих функций:

            Обрезка пробелов и управляющих символов

            Для такой часто встречающейся операции, как удаление пробелов и управляющих символов в начале и в конце строки, есть несколько функций: Trim, TrimLeft, TrimRight, TStringHelper.Trim, TStringHelper.TrimLeft и TStringHelper.TrimRight. При вызове функций TStringHelper.Trim, TStringHelper.TrimLeft и TStringHelper.TrimRight вы можете перечислить, какие символы нужно удалять. Вот пример использования этих функций:

            Выравнивание текста за счёт установки пробелов

            И напоследок ещё пара интересных функций, которые умеют дополнять строку пробелами или другими символами, пока она не станет нужной длины. Это функции TStringHelper.PadLeft и TStringHelper.PadRight. С помощью этих функций, например, для лучшего восприятия можно добавить пробелы в начало чисел, которые вы выдаёте столбиком в консоли или дополнить числа ведущими нулями. Вот пример использования этих функций:

            Вместо заключения

            Итак, в статье я постарался собрать все возможные функции Delphi, которые постоянно нужны при работе со строками. Надеюсь, вы найдёте в этой статье что-то новое и интересное для себя. Если я упустил что-то важное на ваш взгляд, просьба не держать это в себе, а написать об этом в комментариях.

            Insert — Процедура Delphi

            Работа со строками Delphi позволяет извлечь из строки необходимую информацию и представить её в нужном виде. Система предоставляет весь спектр необходимых функций для работы со строками Delphi и преобразования строк Delphi в необходимые форматы:

            • числовой формат, целый и дробный с плавающей точкой;
            • формат времени, даты, даты-времени;
            • преобразование символов к верхнему или нижнему регистру;
            • сравнение строк, поиск в строке и копирование подстроки;
              и многие другие.

            Непосредственно сами строки Delphi поддерживают единственную операцию, так называемую операцию конкатенации, то есть присоединения. Несмотря на «научное» название, операция конкатенации выполняет очень простую процедуру. С помощью операции конкатенации одна строка присоединяется к другой:

            Результирующая строка S будет суммой двух слагаемых строк. Длина строки, то есть количество символов в строке, возвращается встроенной функцией

            function Length(S: String): Integer;

            Delphi работает со строками типа String, в котором длина строки записывается в начале строки, перед первым символом. Поэтому индекс первого символа в строке не 0, а 1. То есть, если:

            S:=’Строка типа String’;

            то S[1] — символ ‘С’, S[2] — символ ‘т’ , последний символ в строке — S[Length(S)], равный ‘g’.

            Однако часто приходится иметь дело со строками типа PChar, которые использует операционая система Windows. В строках типа PChar длина строки определяется специальным символом конца строки — #0. Поэтому для использования функций Windows тип String необходимо предварительно переводить в тип PChar. Преобразование типа String в тип PChar выполняет функция

            function PChar(S: String): PChar;

            Для полноценной работы со строками Delphi используются следующие стандартные процедуры и функции:

            Функции преобразования в числовой формат и обратно

            Выполняя вычисления, используем для ввода данных и отображения результатов следующие функции, работающие со строками Delphi:

            функция IntToStr(N: Integer): String
            Преобразует целое число N в строку.
            функция StrToInt(S: String): Integer
            Преобразует строку S в целое число.
            функция FloatToStr(X: Extended): String
            Преобразует число с плавающей точкой X в строку.
            функция StrToFloat(S: String): Extended
            Преобразует строку S в число с плавающей точкой.

            Процедуры и функции преобразования дат и времени

            Сначала собственно функции, предоставляющие информацию о текущих дате и времени:

            функция Now: TDateTime
            Возвращает текущую дату и время.
            функция Date: TDateTime
            Возвращает текущую дату.
            функция Time: TDateTime
            Возвращает текущее время.

            Далее, функции, работающие с составляющими даты и времени (год, месяц, число, день недели, часы, минуты, секунды и даже миллисекунды):

            функция DayOfWeek(Date: TDateTime): Integer
            Возвращает текущий номер дня недели: 1 — воскресенье, 7 — суббота.
            процедура DecodeDate(Date: TDateTime; var Year, Month, Day: Word)
            Разбивает дату Date на год — Year, месяц — Month и день — Day.
            процедура DecodeTime(Time: TDateTime; var Hour, Min, Sec, MSec: Word)
            Разбивает время Time на час — Hour, минуты — Min, секунды — Sec и миллисекунды — MSec.
            функция EncodeDate(Year, Month, Day: Word): TDateTime
            Объединяет год — Year, месяц — Month и день — Day в значение типа TDateTime.
            функция EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime
            Объединяет час — Hour, минуты — Min, секунды — Sec и миллисекунды — MSec в значение типа TDateTime.

            Наконец, собственно, функции, переводящие дату и время из формата TDateTime в строчный формат:

            функция DateTimeToStr(DateTime: TDateTime): String
            Преобразует дату и время DateTime в строку.
            функция DateToStr(Date: TDateTime): String
            Преобразует дату Date в строку.
            функция TimeToStr(Time: TDateTime): String
            Преобразует время Time в строку.

            Следующие функции работают с параметрами возвращаемой строки. Функции с приставкой Ansi работают в том числе и с кириллическими символами. Если символы в строках предполагаются исключительно латинские, то можно использовать аналогичные функции, но без приставки Ansi:

            функция AnsiLowerCase(const S: String): String
            Возвращает строку S, преобразованную к нижнему регистру.
            функция AnsiUpperCase(const S: String): String
            Возвращает строку S, преобразованную к верхнему регистру.
            функция Length(const S: String): Integer
            Возвращает количество символов в строке S.
            функция Trim(const S: String): String
            Удаляет из строки S начальные и завершающие пробелы и управляющие символы.
            функция TrimLeft(const S: String): String
            Удаляет из строки S начальные пробелы и управляющие символы.
            функция TrimRight(const S: String): String
            Удаляет из строки S завершающие пробелы и управляющие символы.

            Следующие функции сравнивают две строки между собой:

            функция AnsiCompareStr(const S1, S2: String): Integer
            Сравнивает две строки S1 и S2 с учётом регистра символов.
            Возвращает значение 0 если S1>S2
            функция AnsiCompareText(const S1, S2: String): Integer
            Сравнивает две строки S1 и S2 без учёта регистра символов.
            Возвращает значение 0 если S1>S2

            Следующие функции осуществляют поиск в текущей строке подстроки, вставляют, удаляют или заменяют подстроку:

            функция Pos(Substr: String; Str: String): Integer
            Возвращает позицию (индекс) первого вхождения Substr в строке Str. Если Substr нет в Str, возвращает 0.
            функция Insert(Source: String; var S: String; Index: Integer): Integer
            Вставляет строку Source в строку S, начиная с номера символа, равного Index
            процедура Delete(var S: String; Index, Count: Integer)
            Удаляет из строки S подстроку, начинающуюся с номера символа, равного Index, и содержащую до Count символов.
            функция StringReplace(const S, OldPattern, NewPattern: string; Flags: TReplaceFlags): String
            Заменяет в строке S подстроку OldPattern на строку NewPattern с учётом флага TReplaceFlags. Для работы с этой функцией нужно создать переменную типа TReplaceFlags — это множество, и включить в него одно или оба значения из следующих:
            rfReplaceAll — будут заменены все вхождения. Если это значение не будет включено во множество, то будет заменено только первое вхождение;
            rfIgnoreCase — замена будет без учёта регистра символов. Если это значение не будет включено во множество, то замена будет чувствительна к регистру символов.

            Наконец, функция копирования части строки:

            функция Copy(S: String; Index, Count: Integer): String
            Возвращает подстроку строки S, начиная с номера символа, равного Index и содержащую до Count символов.

            Помимо прочего, эту функцию можно использовать для вывода нецелого числа с нужным количеством цифр после запятой. Для этого, сначала получаем строку из числа формата Real, затем находим функцией Pos позицию запятой в этой строке, прибавляем нужное количество и копируем в результат это количество символов. Вот готовая функция:

            function RealToStr(X: Real; Count: Integer): String; //Count — количество цифр после запятой
            var S: String;
            N: Integer;
            begin
            S:=FloatToStr(X); //после запятой — длинная последовательность цифр
            //DecimalSeparator — константа, содержащая истинный разделитель целой и дробной частей числа N:=Pos(DecimalSeparator, S); //позиция запятой в строке
            //вычисляем длину строки с нужным количеством знаков после запятой:
            if N=0 //если в строке нет запятой — это целое число, и
            then N:=Length(S) //тогда просто выводим это число
            else N:=N+Count; //иначе вычисляем длину строки
            Result:=Copy(S, 1, N); //копируем часть строки в результат
            end;

            Или вот, к примеру, текст модуля, обеспечивающего ввод в компонент Edit только чисел.

            Insert — Процедура Delphi

            В этом уроке мы более подробно разберем различные методы работы со строками. Научимся производить простые операции копирования, поиска, вставки и т.п.
            В прошлом уроке мы рассмотрели достаточно полезные функции преобразования чисел в строки и наоборот. Теперь давайте рассмотрим несколько функций работы непосредственно с самими строками.

            Сложение строк реализуется практически как и сложение обыкновенных чисел следующим образом:
            [cc lang=»delphi»]var
            a,b,c:string;
            begin
            b := ‘Cybern.ru’;
            c := ‘ is a best website’;
            a := b + c;
            // в результате строка a будет выглядеть так: «Cybern.ru is a best website»
            end;[/cc]

            Получение длины строки в Delphi реализуется при помощи функции Length, которая возвращает в качестве результата целочисленное число.
            [cc lang=»delphi»]var
            a:string;
            count:integer;
            begin
            a := ‘Cybern.ru’; // 9 символов
            count := Length(a);
            // в результате переменная count будет равна 9
            end;[/cc]

            В любой строке можно получать доступ к каждому ее символу. Таким образом, можно рассматривать строку как одномерный массив символов, т.е. можно обращаться к каждому символу по его индексу. Важно учесть, что индексы в строках типа String нумеруются не с 0, а c 1, т.е. индекс первого символа равен 1, а индекс последнего символа равен Length(s) (длине этой строки).
            [cc lang=»delphi»]var
            a, b:string;
            c: char;
            begin
            a := ‘Cybern.ru’; // 9 символов
            b := a[3]; // символ ‘b’
            c := a[3]; // можно использовать тип Char, который хранит в себе не более 1 символа
            c := a[length(a)]; // получение последнего символа ‘u’
            end;[/cc]

            [cc lang=»delphi»]var
            a, b:string;
            begin
            a := ‘CyberN.RU’;
            b := LowerCase(a); // строка b будет равна ‘cybern.ru’
            b := UpperCase(a); // строка b будет равна ‘CYBERN.RU’
            end;[/cc]

            Для поиска позиции определенной подстроки в строке используется функция Pos, возвращающая в результате своего вхождения начальный индекс этого вхождения в строке. Этой функции необходимо передать два параметра: подстроку, которую ищем, и строку, в которой производим поиск. Рассмотрим простой пример.
            [cc lang=»delphi»]var
            a, b:string;
            с: integer;
            begin
            a := ‘CyberN.RU is the best website about programming’;
            b := ‘website’;
            c := pos(b, a); // c = 23
            end;[/cc]
            Также существует еще одна аналогия функции pos, но имеющая немного больше возможностей — PosEx. Она позволяет производить поиск подстроки начиная с определенного индекса в строке. Но для работы с этой функцией необходимо добавить в раздел uses модуль StrUtils.
            [cc lang=»delphi»]var
            a, b:string;
            с: integer;
            begin
            a := ‘123abc123123123’;
            b := ‘123’;
            c := PosEx(b, a, 4); // c = 7
            end;[/cc]
            Как видите, преимущество PosEx заключается в том, что при поиске можно игнорировать определенные вхождения до указанного индекса. Это бывает очень удобно.

            Функция Insert позволяет вставить подстроку внутрь исходной строки, начиная с указанного индекса. При этом вставка происходит со сдвигом последующих символов вправо на длину вставляемой подстроки.
            [cc lang=»delphi»]var
            a, b:string;
            begin
            a := ‘CyberN.RU is the website about programming’;
            b := ‘best ‘;
            Insert(a, b, 13); // a = «CyberN.RU is the best website about programming»
            end;[/cc]

            Процедура Delete позволяет удалить из строки указанное количество символов, начиная с указанного индекса в строке. При этом удаление происходит со сдвигом последующих символов на длину удаляемой подстроки влево.
            [cc lang=»delphi»]var
            a:string;
            begin
            a := ‘123123abc123123’;
            Delete(a, 7, 3); // a = «123123123123»
            end;[/cc]

            Функция Copy позволяет получить дубликат подстроки определенной длинны, начинающейся с символа с указанным индексом.
            [cc lang=»delphi»]var
            a, b:string;
            begin
            a := ‘cybern.ru is the best website about programming’;
            b := Copy(a, 1, 9); // b = «cybern.ru»
            end;[/cc]

            Для замены одной подстроки на другую подстроку внутри исходной строки используют функцию StringReplace. Нужно признать, что функция довольно удобная и обойти стороной ее никак нельзя. Довольно полезной возможностью этой функции является то, что она может заменять сразу несколько вхождений одной подстроки на другую, а также может игнорировать регистр. Последние две возможности являются опциональными (необязательными) и при необходимости их можно не использовать. Рассмотрим пример:
            [cc lang=»delphi»]var
            a, b, c: string;
            begin
            a := ‘aBc Abc abC 123 cba cba cba’; // исходная строка
            b := ‘abc’; // заменяемая подстрока
            c := ‘test’; // заменяющая подстрока
            // Далее параметр [rfReplaceAll,rfIgnoreCase] обозначают как раз те самые опции в работе функции.
            // Называются такие параметры «флагами».
            // Такие флаги обязательно нужно указывать внутри квадратных скобок.
            // Сами флаги перечисляются через запятую.
            // Все флаги, находящиеся внутри квадратных скобок являются обычным параметром функции.
            // Флаг rfReplaceAll говорит функции, что нужно будет производить замену всех вхождений.
            // Если этот флаг убрать (тогда выглядеть флаги будут так «[rfIgnoreCase]»),
            // то заменится только первое вхождение в строке a.
            // Флаг rfIgnoreCase указывает, что при поиске вхождений строк b регистр учитываться не будет.
            // Если все флаги вам не нужны, то это НЕ значит, что параметр вовсе не нужно указывать.
            // В таком случае укажите в качестве флагов «[]».
            a := StringReplace(a,b,c, [rfReplaceAll,rfIgnoreCase]);
            // В результате строка a будет содержать «test test test 123 cba cba cba»
            end;[/cc]
            [note]Если вы не помните какие флаги есть у функции, то лучше укажите сначала «[«, а затем нажмите «Ctrl+Пробел», после чего откроется список с подсказками, в котором будут перечислены все возможные флаги. [/note]

            Регулярные выражения позволяют осуществлять очень широкий спектр различных возможностей, связанный с поиском, выбором и анализом строки. Подробнее о регулярных выражениях вы можете прочитать тут.

            Илон Маск рекомендует:  Что такое код cpdf_close
            Понравилась статья? Поделиться с друзьями:
            Кодинг, CSS и SQL