Формирование краткой библиографической записи
[ Анна Рахманина ]
При создании программного обеспечения для нужд книжного бизнеса очень часто возникает необходимость формировать
в качестве описания книги правильную краткую библиографическую запись. На самом деле, это совсем не тривиальная задача,
алгоритм объединения различных атрибутов описания достаточно сложен и громоздок.
В данном материале предлагается готовый код формирования такой записи по заданному набору данных (TDataSet)
или по списку (TStringList) библиографических атрибутов UNIMARC.
Компонент разработан для формирования записей для книг (в т.ч. CD, дисков, аудио и видеокассет) и монет.
Для формирования текстовой записи ему необходимо передать набор атрибутов описания книги (монеты) в стандарте UNIMARC.
Используемое множество атрибутов указано ниже.
Пример. Рассмотрим пример использования компонента. Пусть набор данных содержит следующие записи:
ATTR_ID | ATTR_VALUE | ATTR_NAME |
F010a | 5-87365-046-2 | ISBN |
F210d | 1999 | Дата издания |
F215c | 4 л. цв. ил. | Другие уточнения физических характеристик |
F210a | М. | Место издания |
F210c | Тролль | Издатель |
F200a | Японская поэзия | Основное заглавие |
F215a | 662 | Сведения о количестве страниц |
Тогда нижеприведенный код вернет следующую краткую запись:
Японская поэзия. - М.: Тролль, 1999. - 662 с.: 4 л. цв. ил. - ISBN 5-87365-046-2
var
sFullBiblioRecord: string;
begin
ShortBiblioGenerator.FieldPrefix := 'F';
ShortBiblioGenerator.DataSet := tblAttrValues;
tblAttrValues.Open;
sFullBiblioRecord :=
ShortBiblioGenerator.Execute(tblAttrValuesATTR_ID, tblAttrValuesATTR_VALUE);
...
Исходный код компонента приведен ниже.
Untitled
{
===Компонент формирования краткой библиографической записи===
Свойства, доступные через Инспектор объектов:
FieldPrefix - префикс идентификатора поля биб. описания в передаваемом
наборе данных
(возможны разные варианты - отсутствие префикса, префикс f)
в случае наличия перфикса указывать обязательно для корректной
обработки набора данных
DescriptionType - тип библиографического описания. Для разных типов - разные
краткие записи. В данной версии поддерживается формирование
краткой биб. записи для следующих типов:
dtBook - книжное описание
dtCoin - описание монет
DataSet - вертикальный набор данных
Методы:
Execute - формирует краткую библиографическую запись.
function Execute: string; - по свойству DataSet
function Execute(SourceDataSet: TDataSet): string; - по SourceDataSet
function Execute(SourceStringList: TStringList): string; - по Stringlist
В качестве вх. парметра - вертикальный набор данных
или СтрингЛист в виде "идентификатор = значение"
После выполнения метода Execute доступными для чтения делаются следующие свойства:
BiblioRecord - краткая библиогрфическая запись
BiblioHeader - заголовок краткой библиографической записи
BiblioBody - тело краткой библиографической записи (запись без заголовка)
arakh & xelby, апрель 2002
}
unit gcShortBiblioGenerator;
{$I glDEF.INC}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, db,
TypInfo {$IFDEF GLVER_D6}{DesignIntf, DesignEditors, VCLEditors}{$ELSE} {$IFDEF GLVER_D5},dsgnintf{$ENDIF} {$ENDIF};
type
TDescriptionType = (dtBook, dtCoin); //???
TShortBiblioGenerator = class(TComponent)
private
FFieldPrefix : string;
FBiblioRecord: string;
FBiblioHeader: string;
FBiblioBody : string;
FDescriptionType: TDescriptionType;
FDataSet: TDataSet;
{ Private declarations }
procedure PrepareStringList(SourceStringList: TStringList);
protected
function GenerateBiblioRecord(SourceStringList: TStringList): string;
public
property BiblioHeader: string read FBiblioHeader;
property BiblioBody: string read FBiblioHeader;
property BiblioRecord: string read FBiblioRecord;
function Execute: string; overload;
function Execute(SourceDataSet: TDataSet): string; overload;
function Execute(SourceStringList: TStringList): string; overload;
published
property FieldPrefix: string read FFieldPrefix write FFieldPrefix; // префикс для полей UNIMARK
property DescriptionType: TDescriptionType read FDescriptionType write FDescriptionType default dtBook;
property DataSet: TDataSet read FDataSet write FDataSet;
end;
{
TShortBiblioGenerator_Editor = class(TComponentEditor)
procedure ExecuteVerb(Index: Integer); override;
function GetVerb(Index: Integer): string; override;
function GetVerbCount: Integer; override;
end;
}
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Globus Special', [TShortBiblioGenerator]);
end;
{ TShortBiblioGenerator }
function TShortBiblioGenerator.Execute: string;
begin
// использовать родной DataSet
Result := Execute(DataSet);
end;
function TShortBiblioGenerator.Execute(SourceDataSet: TDataSet): string;
var
SourceStringList: TStringList;
AttrValue : string;
begin
if not Assigned(SourceDataSet) then
raise Exception.Create('Параметр DataSet не задан');
SourceStringList := TStringList.Create;
try
SourceDataSet.Active := true;
{ формирование SourceStringList по DataSet }
with SourceDataSet do
begin
First;
while not eof do
begin
AttrValue := trim(FieldByName('attr_id').asString) + '=' + trim(FieldByName('attr_value').asString);
SourceStringList.Add(AttrValue);
Next;
end;
end;
PrepareStringList(SourceStringList);
Result := GenerateBiblioRecord(SourceStringList);
finally
SourceStringList.Free;
end;
end;
function TShortBiblioGenerator.Execute(SourceStringList: TStringList): string;
begin
if not Assigned(SourceStringList) then
raise Exception.Create('Параметр StringList не задан');
PrepareStringList(SourceStringList);
Result := GenerateBiblioRecord(SourceStringList);
end;
{ Формирует запись по данным из StringList }
function TShortBiblioGenerator.GenerateBiblioRecord(SourceStringList: TStringList): string;
function ValueByID(ID:string):string;
begin
if SourceStringList.IndexOfName(ID) <> -1 then
result := trim(SourceStringList.Values[ID])
else
result := '';
end;
var
ch:char; // символ, который указывается в сведении о кол-ве страниц
publ:integer;
pls:integer;
NumOfChar:integer; // число символов в заголовке
slPublishers, slPlaces:TStringList;
i,j:integer;
F205aExists, F205Exists, F210Exists, F215aExists, F215acExists,
F215acdExists, F215aeExists, F225aExists, F010Exists, exi : Boolean;
Header,Body, BR: string; // заголовок, тело, полная запись
begin
//.. если исходный СтрингЛист - пустой
if SourceStringList.Count = 0 then
begin
BR:='';
Exit;
end;
//.. создание списков для множественных значений издателей и мест идания
slPublishers:=TStringList.Create;
slPlaces:=TStringList.Create;
slPublishers.Clear;
slPlaces.Clear;
//.. инициализация переменных, нужных для формирования записи
publ :=0;
BR :='';
ch :='с'; // по умолчанию - страницы
Header:='';
Body :='';
if DescriptionType = dtCoin then // краткая запись для монет
begin
BR :=ValueByID('200a');
if BR <> '' then
BR := BR + ' - ';
BR := BR+ValueById('210d')+#13#10;
Header := AnsiUpperCase(BR); //это заголовок
NumOfChar := Length(Header);
if ValueByID('225a') <> '' then
BR:= BR + 'Серия: '+ValueByID('225a');
if ValueByID('3119') <> '' then
BR:= BR + ' Каталожный номер: ' + ValueByID('3119');
if ValueByID('010d') <> '' then
BR := BR + ' Номинал: ' + ValueByID('010d');
if ((ValueByID('308a') <> '') or (ValueByID('9155') <> '')) then
BR := BR + ' Качество: ' + ValueByID('308a') + ' ' + ValueByID('9155');
if ValueByID('9157') <> '' then
BR := BR + ' Вес: ' + ValueById('9157');
if ValueByID('215d') <> '' then
BR := BR + ' Диаметр: ' + ValueByID('215d');
Body := copy(BR, NumOfChar+1, Length(BR)-NumOfChar);
FBiblioRecord := BR;
FBiblioHeader := Header;
FBiblioBody := Body;
exit;
end;
if ValueById('205a') <> '' then // 205aExists
F205aExists := true; {b10}
//если присутствуют поля F205a или F205b // 205Exists
if (ValueById('205a') <> '') or (ValueById('205b') <> '') then
F205Exists := true; {b1}
//если присутствуют поля F210a или F210c или F210d // 210Exists
if (ValueById('210a') <> '') or
((ValueById('210c') <> '') and (ValueById('210c') <> 'Б.и.')) or
(ValueById('210d') <> '') then
F210Exists := true; {b2}
//если присутствуют поля F215a или F215c или F215d или F215e // 215Exists
if ValueById('215a') <> '' then
F215aExists := true; //есть F215a {b3}
if F215aExists or (ValueById('215c') <> '') then
F215acExists :=true; //есть F215a или F215c {b4}
if F215acExists or (ValueById('215d') <> '') then
F215acdExists :=true; //есть F215a или F215c или F215d {b5}
if F215aExists or (ValueById('215e') <> '') then
F215aeExists :=true; {b9}
//if 215acdExists or (ValueById('215d') <> '') then
// 215acdExists := true; //есть F215a или F215c или F215d или F215e {b6}
if ValueById('225a') <> '' then // есть 225а
F225aExists := true; {b7}
//..если присутствуют поля F010a или F010b или F0109 //010Exists
if (ValueById('010a') <> '') or
(ValueById('010b') <> '') or
(ValueById('0109') <> '') then
F010Exists := true; {b8}
//..начинаем формировать запись
//.. в зависимости от типа товара сведения о кол-ве страниц меняются
if (ValueById('215a') = 'дискета') or
(ValueById('215a') = 'CD-ROM') or
(ValueById('215a') = 'цифровой диск') then
ch:='д';
if (ValueById('215a') = 'аудиокассета') or
(ValueById('215a') = 'видеокассета') then
ch:='к';
if ValueById('215a') = 'цифровой магнитофон' then
ch:='м';
{*---Заглавие---}
//---Заголовок Б.З.---
if ValueById('700a') <> '' then // если есть атрибут F700a
begin
BR := BR + ValueById('700a');
if ValueById('700c') <> '' then
BR := BR + ' ' + ValueById('700c');
if ValueById('700d') <> '' then
BR := BR + ' ' + ValueById('700d');
if ValueById('700b') <> '' then
BR := BR + ' ' + ValueById('700b');
if (length(BR) <> 0) and (BR[length(BR)] <> '.') then
BR := BR + '.';
Header := AnsiUpperCase(BR) + ' ';
BR := BR + ' ';
end;
//---Основное заглавие---
if ValueById('200a') <> '' then
begin
BR := BR + ValueById('200a');
Header := Header + ValueById('200a');
NumOfChar := length(Header)
end;
//---Параллельное заглавие---
if ValueById('200d') <> '' then
BR := BR + ' ' + '=' + ' ' + ValueById('200d');
//---Сведения, отн. к заглавию---
if ValueById('200e') <> '' then
BR := BR + ':' + ' ' + ValueById('200e');
//---Первые сведения об ответственности---
if ValueById('200f') <> '' then
begin
exi := true;
BR := BR + ' ' + '/ ' + ValueById('200f');
end;
//---Послед. сведения об ответственности---
if ValueById('200g') <> '' then
begin
if not exi then
BR := BR + ' / ' + ValueById('200g')
else BR := BR + '; ' + ValueById('200g');
end;
exi := false;
//---Обозначение тома---
if ValueByID('200v') <> '' then
BR := BR + '. ' + ValueByID('200v');
//---Номер тома---
if ValueByID('200h') <> '' then
BR := BR + ' ' + ValueByID('200h');
//---Номер тома---
if ValueByID('200i') <> '' then
BR := BR + '. ' + ValueByID('200i');
{---Сведения об издании---}
if {b1} F205aExists then
begin
if (length(BR) <> 0) and (BR[length(BR)] <> '.') then
BR := BR + '.';
BR := BR + ' - ';
if ValueById('205a')<> '' then
begin
BR := BR + ValueById('205a');//основные сведения
exi := true;
end;
if ValueById('205b') <> '' then
if exi then
BR := BR + ', ' + ValueById('205b'); //дополнит. сведения
exi:=false;
end;
{---Сведения о выходных данных---}
if F210Exists then
begin
if (length(BR) <> 0) and (BR[length(BR)] <> '.') then
BR := BR + '.';
BR := BR + ' - ';
//---Место издания---
//заполняем список мест и издателей
for i := 0 to SourceStringList.Count - 1 do
begin
if SourceStringList.Names[i] = '210a' then
slPlaces.Add(SourceStringList.Values[SourceStringList.Names[i]]);
if SourceStringList.Names[i] = '210c' then
slPublishers.Add(SourceStringList.Values[SourceStringList.Names[i]]);
end;
{-----}
i := 0;
for i := 0 to slPlaces.Count - 1 do
begin
if i <> 0 then BR := BR + ', ';
BR := BR + slPlaces[i];
if slPublishers.Count - 1 >= i then
BR := BR + ': ' + slPublishers[i];
end;
if slPlaces.Count = 0 then i := 0;
if slPublishers.Count - 1 >= i then
for j := i to slPublishers.Count - 1 do
BR := BR + ', ' + slPublishers[j];
{-----}
//---Дата издания---
if ValueById('210d') <> '' then
BR := BR + ', ' + ValueById('210d');
end;
{-----Количественная характеристика-------}
if {b6} F215aeExists then
begin
if (length(BR) <> 0) and (BR[length(BR)] <> '.') then
BR := BR + '.';
BR := BR + ' - ';
//---Сведения о кол-ве страниц---
if ValueById('215a') <> '' then
begin
BR := BR + ValueById('215a') + ' ' + ch + '.';
exi := true;
end;
//---Др. уточн-я физ. хар-к---
if ValueById('215c') <> '' then
if exi then
BR := BR + ': ' + ValueById('215c');
exi:=false;
//---Размеры---
if ValueById('215d') <> '' then
if F215acExists then
BR := BR + '; ' + ValueById('215d') + ' см.';
//---Размеры---
if ValueById('215e') <> '' then
if F215acdExists then
BR := BR + ' ' + ValueById('215e') + ' см.';
end;
{-----Сведения о серии-------}
if F225aExists then
begin
if (length(BR) <> 0) and (BR[length(BR)] <> '.') then
BR := BR + '.';
//---Сведения, отн. к заглавию----
BR := BR + ' - (' + ValueById('225a');
if ValueById('225e') <> '' then
BR := BR + ': ' + ValueById('225e');
//---Сведения об ответственности----
if ValueById('225f') <> '' then
BR := BR + ' / ' + ValueById('225f');
//---ISSN серии----
if ValueById('225x') <> '' then
BR := BR + ', ' + ValueById('225x');
//---Номер части серии----
if ValueById('225h') <> '' then
BR := BR + '; ' + ValueById('225h');
//---Основное заглавие подсерии---
if ValueById('225i') <> '' then
BR := BR + '. ' + ValueById('225i');
//---Номер тома серии или подсерии---
if ValueById('225v') <> '' then
BR := BR + '; ' + ValueById('225v');
BR := BR + ')';
end;
{-----ISBN--------}
if F010Exists then
begin
if (length(BR) <> 0) and (BR[length(BR)] <> '.') then
BR := BR + '.';
BR := BR + ' - ';
//---Номер ISBN---
if ValueById('010a') <> '' then
begin
BR := BR + 'ISBN ' + ValueById('010a');
exi := true;
end;
//---Уточнение к ISBN---
if (ch = 'с') and (ValueById('010b') <> '') then
begin
if exi then BR := BR + ' (';
BR := BR + ValueById('010b');
if exi then BR := BR + ')';
end;
//---Сведения о тираже---
if ValueById('0109') <> '' then
begin
if (ValueById('010b') <> '') or exi then
BR := BR + ', ';
BR := BR + ValueById('0109') + ' экз.';
end;
end;
Body := copy(Br,NumOfChar + 1, Length(BR) - NumOfChar);
FBiblioRecord := BR; // Полная краткая библиографическая запись
FBiblioHeader := Header; // заголовок краткой библиографической записи
FBiblioBody := Body; // тело краткой библиографической записи
result := BR;
end;
procedure TShortBiblioGenerator.PrepareStringList(SourceStringList: TStringList);
var
st, Value :string;
i :integer;
PrefixLength :integer;
begin
PrefixLength := Length(FieldPrefix);
for i := 0 to SourceStringList.Count - 1 do
begin
st := SourceStringList.Names[i];
Value := Copy(SourceStringList[i], pos('=',SourceStringList[i])+1, 500);
if FieldPrefix <> '' then
if copy(st,1,PrefixLength) = FieldPrefix then delete(st,1,PrefixLength);
AnsiLowerCase(st);
SourceStringList[i] := st + '=' + Value;
end;
end;
{ TglRep_Editor }
{
function TShortBiblioGenerator_Editor.GetVerbCount: Integer;
begin
Result := 1;
end;
function TShortBiblioGenerator_Editor.GetVerb(Index: Integer): string;
begin
case Index of
0: Result := 'Execute'; // тестовый вызов генератора
end;
end;
procedure TShortBiblioGenerator_Editor.ExecuteVerb(Index: Integer);
begin
case Index of
0:
with (Component as TShortBiblioGenerator) do
begin
Execute();
ShowMessage(BiblioRecord);
end;
end;
end;
}
end.
Приведенный компонент может быть по Вашему запросу преобразован в компонент ActiveX для использования в любых
средах разработки под MS Windows, в.т.ч. VisualBasic, PowerBuilder, 1C etc.
Весь материал, размещенный на сайте www.bookresearch.ru, является собственностью авторов соответствующих материалов.
Любая перепечатка и перенос материалов на другие сайты возможны только с разрешения авторов и администратора сайта.
Любой может предложить свой материал для публикации у нас. Пишите администратору сайта.
|