Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Delphi 2

Автор: RostY
Дата сообщения: 13.03.2007 14:39
OOD
FanAndTemp.exe -- отсутствует провайдер или требуемое устройство.
Everest все показывает.
(ОС: winXP SP2, Win 2k Server)
Автор: OOD
Дата сообщения: 13.03.2007 15:24
RostY

Цитата:
Everest все показывает.

У Вас есть исходники Everest ?
Автор: George_Lucky
Дата сообщения: 13.03.2007 15:27
Вопрос,
процедура получает в качестве параметра obj: TObject

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

а пока получается такая лабуда:

if obj is TEdit then
str := TEdit(obj).Text
else if obj is TmyEdit then
str := TmyEdit(obj).Text;
Автор: OdesitVadim
Дата сообщения: 13.03.2007 15:51
George_Lucky
В таком случае надо юзать интерфейсы. Или сделать у них общего предка.
Автор: relictus
Дата сообщения: 13.03.2007 16:50
Можно ли как-то ускорить нижеприведенный код копирования файлов (в случае с десятками тысяч файлов):

Код: function WindowsCopyFile(FromF, ToF : string) : boolean;
var F: TShFileOpStruct;
begin
F.Wnd := 0; F.wFunc := FO_COPY;
FromF:=FromF+#0; F.pFrom:=pchar(FromF);
ToF:=ToF+#0; F.pTo:=pchar(ToF);
F.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_NOCONFIRMMKDIR or FOF_SIMPLEPROGRESS;
result:=ShFileOperation(F) = 0;
end;
Автор: SERGE_BLIZNUK
Дата сообщения: 13.03.2007 17:28
relictus
Цитата:
Полчаса работы, а результат такой (еще копировать около 300 Мб)
Вы меня, конечно, извините, но...
вопросы следующие:
1) это разовое копирование? Может его не стоит делать на Дельфи?
2) Можно попробовать копировать файл через старый способ BlockRead/BlockWrite
либо через TFileStream...
3) теоретически запуск копирование каждого файла в отдельном потоке TThread может увеличит производительность за счёт распараллеливания...
4) как вы перебираете файлы FromF - может быть задержки именно на получении имени файлов?
5) если копировать через командную строчку ( COPY ) - получается быстрее? Насколько?...


Автор: RostY
Дата сообщения: 13.03.2007 17:39
Кажется, здесь уже проскакивала тема о копировании файлов. Можно попробовать копировать с использованием буффера[more] procedure CopyFile(file1,file2: string);
var
FromF, ToF: file;
NumRead, NumWritten: Integer;
Buf: array[1..2048] of Char;
begin
begin
AssignFile(FromF, file1);
Reset(FromF, 1);
AssignFile(ToF, File2);
Rewrite(ToF, 1);
repeat
BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
BlockWrite(ToF, Buf, NumRead, NumWritten);
until (NumRead = 0) or (NumWritten <> NumRead);
CloseFile(FromF);
CloseFile(ToF);
end;
end;
[/more], можно через потоки [more] procedure FileCopy(const SourceFileName, TargetFileName: string);
var
S, T : TFileStream;
begin
S := TFileStream.Create(sourcefilename, fmOpenRead );
try
T := TFileStream.Create(targetfilename, fmOpenWrite or fmCreate);
try
T.CopyFrom(S, S.Size ) ;
FileSetDate(T.Handle, FileGetDate(S.Handle));
finally
T.Free;
end;
finally
S.Free;
end;
end;
[/more], можешь попробовать через CopyFile(), можешь попробовать отключить антивирус

Добавлено:
еще кусок кода (не мой, автора, пусть меня извинит, не помню)
[more]
procedure FastFileCopy(const InfileName, OutFileName: string);
const
BufSize = 3*4*4096; { 48Kbytes дает прекрасный результат }
type
PBuffer = ^TBuffer;
TBuffer = array [1..BufSize] of Byte;
var
Size : integer;
Buffer : PBuffer;
infile, outfile : file;
SizeDone, SizeFile: Longint;
begin
if (InFileName <> OutFileName) then
begin
buffer := nil;
AssignFile(infile, InFileName);
System.Reset(infile, 1);
try
SizeFile := FileSize(infile);
AssignFile(outfile, OutFileName);
System.Rewrite(outfile, 1);
try
SizeDone := 0; New(Buffer);
repeat
BlockRead(infile, Buffer^, BufSize, Size);
Inc(SizeDone, Size);
BlockWrite(outfile,Buffer^, Size)
until
Size < BufSize;
FileSetDate(TFileRec(outfile).Handle,
FileGetDate(TFileRec(infile).Handle));
finally
if Buffer <> nil then
Dispose(Buffer);
System.close(outfile)
end;
finally
System.close(infile);
end;
end
else
raise EInOutError.Create('File cannot be copied into itself');
end;
[/more]

Добавлено:
при использовании буффера желательно поставить размер буффера = N * [размер кластера диска]
Автор: svs123456789
Дата сообщения: 13.03.2007 20:09
как правильно организовывать в Delphi связь многие ко многим
и как автоматизировать этот процесс?

2 таблицы A и B связанные многие-ко-многим (черз промежуточную таблицу AB) в базе данных

соответсвенно 3 dataset в delphi
в случае master-detail делфи автоматизирует работу указанием свойства мастер соурсе у подчиненного датасета
и передачей в подчиненный запрос параметра :id из главного запроса

но у промежуточной таблицы AB есть только одно поле для ссылки на главный запрос, а она (AB) должна быть подчиненной сразу двум таблицам и А и B

как правильно добавлять и удалять записи из табоицы B ?
Автор: relictus
Дата сообщения: 13.03.2007 20:11
SERGE_BLIZNUK

Цитата:
1) это разовое копирование?

Это типа конвертора кэша двух разных программ... операция, в принципе, одноразовая: надо конвертировать одну директорию с тысячами небольших (10-20 кило) файлов вида tqrstqsststrt.jpg в другую директорию, но уже разбитую по такому принципу: каждая буква имени картинки - это одноименная поддиректория, т.е. вышеприведенный пример должен записаться в папку ../t/q/r/s/t/q/s/s/t/s/t/r/t.jpg с созданием (если они отсутствуют) этих самых поддиректорий.
Как это можно сделать оптимально быстро? Не спрашивая юзера о создании поддиректорий...
Автор: Solnake
Дата сообщения: 13.03.2007 20:15
svs123456789
Мой тебе совет - учи SQL. Юзать отдельно датасет для каждй таблички - тока в книгах видел.
СКБД какая?
Или опиши проблему подробнее, поскажу как зделать по другому.

Добавлено:
relictus

Код: procedure Copy(aDirFrom, aDirTo, aMask: string);
var
OpStruc: TSHFileOpStruct;
FromBuf, ToBuf: array [0..128] of Char;
begin
FillChar(FromBuf, SizeOf(FromBuf), 0);
FillChar(ToBuf, SizeOf(ToBuf), 0);
StrPCopy(FromBuf, aDirFrom+aMask);
StrPCopy(ToBuf, aDirTo);
try
with OpStruc do
begin
wFunc:= FO_COPY;
pFrom:= @FromBuf;
pTo:= @ToBuf;
fFlags:= FOF_NOCONFIRMATION;
fAnyOperationsAborted:= False;
hNameMappings:= nil;
lpszProgressTitle:= nil;
end;
SHFileOperation(OpStruc);
Log('Files are copied successfully'+
' <From>: '+aDirFrom+
' <To>: '+aDirTo);
except
on e:Exception do
Log('Error at copying files into '+aDirTo+#13+#13+e.Message);
end;
Автор: andead
Дата сообщения: 13.03.2007 23:25
greenpc

Цитата:
пример XML в студию
может FindNode, но это пока догадки

есть XML файл (упрощённая версия):


Код: <?xml version="1.0" encoding="utf-8" ?>

<ProvidersList>
<provider name="asd" id="0" />
<provider name="sdf" id="1" />
<provider name="dsf" id="2" />
</ProvidersList>
Автор: VadimLou
Дата сообщения: 14.03.2007 00:05
Windows API CompareString

Блин, неправильно работают ф-ции сравнения строк AnsiCompareXXX.
Т.к. они являются обкруткой вокруг виндячей CompareString то проблема именно в последней.

Вот пример кода с ошибкой для буквы "Ё".

asrt;

{$APPTYPE CONSOLE}

uses
Windows, SysUtils, Classes;

const
sRU: array[ 0 .. 3 ] of string = (
'ЛБ',
'ЛЕ',
'ЛБС',
'ЛЕС'
);
sRU2: array[ 0 .. 3 ] of string = (
'ЛБ',
'ЛЕ',
'ЛБС',
'ЛЕС'
);
var
i, iCmp: Integer;
S1, S2, sCmp: string;
L1, L2: Integer;
S1a, S2a: string;
begin
Writeln('------------------------');

S2 := 'ЛЁ';
L2 := Length(S2);
SetLength(S2a, Length(S2));
AnsiToOEM( PChar(S2), PChar(S2a) );

for i := 0 to High(sRU) do
begin

S1 := sRU[i];
L1 := Length(S1);

// AnsiCompareText:
iCmp := Windows.CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE,
PChar(S1), L1, PChar(S2), L2) - 2;

case iCmp of
-1: sCmp := '< ';
0: sCmp := ' = ';
1: sCmp := ' >';
else
sCmp := '?('+IntToStr(iCmp)+')';
end;

SetLength(S1a, Length(S1));
AnsiToOEM( PChar(S1), PChar(S1a) );

Writeln(S1a:5, ' ', sCmp:9, ' ', S2a);

end;


S2 := 'ЛР';
L2 := Length(S2);
SetLength(S2a, Length(S2));
AnsiToOEM( PChar(S2), PChar(S2a) );

Writeln('------------------------');

for i := 0 to High(sRU2) do
begin

S1 := sRU2[i];
L1 := Length(S1);

// AnsiCompareText:
iCmp := Windows.CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE,
PChar(S1), L1, PChar(S2), L2) - 2;

case iCmp of
-1: sCmp := '< ';
0: sCmp := ' = ';
1: sCmp := ' >';
else
sCmp := '?('+IntToStr(iCmp)+')';
end;

SetLength(S1a, Length(S1));
AnsiToOEM( PChar(S1), PChar(S1a) );

Writeln(S1a:5, ' ', sCmp:9, ' ', S2a);

end;
Writeln('------------------------');

end.

Результат работы:
------------------------
ЛБ < ЛЁ
ЛЕ < ЛЁ
ЛБС < ЛЁ
ЛЕС > ЛЁ ** тут должно быть наоборот
------------------------
ЛБ < ЛР
ЛЕ < ЛР
ЛБС < ЛР
ЛЕС < ЛР
------------------------

Ни у кого нету замены для системной CompareString ?

Кстати для уникодного CompareStringW теже яйца... не любят они славян ...

Автор: greenpc
Дата сообщения: 14.03.2007 08:25
andead
думаю без цикла не получится.
XML это тотже текстовый документ.
У тебя id аттрибут узла provider, а поиск сделан
по узлам тем же циклом ( по крайней мере в тех компонентах которые я смотрел)
[more]
FXmlDoc := TNativeXml.Create;
try
FXmlDoc.LoadFromFile(fName);
if assigned(FXmlDoc.Root) then
with FXmlDoc.Root do
for j := 0 to NodeCount - 1 do
if Nodes[j].AttributeByName['id']='** что ищем**' then ....;
finally
FreeAndNil(FXmlDoc);
end;
[/more]
Автор: nEJIbMEHb3
Дата сообщения: 14.03.2007 09:20
Похоже хотят именно FindNode если ограничение на цикл.
Автор: svs123456789
Дата сообщения: 14.03.2007 09:37
Solnake

Цитата:
Мой тебе совет - учи SQL. Юзать отдельно датасет для каждй таблички - тока в книгах видел.

а ты можешь сделать sql команды без создания объекта типа tdataset ?
Автор: greenpc
Дата сообщения: 14.03.2007 09:42
nEJIbMEHb3

Цитата:
FindNode
ищет узел, а не аттрибуты

VadimLou
1. Убери код в теги more
2. ф-ции сравнения работают правильно !
ошибка в том что код буквы Ё - 401 и находится она перед всем алфавитом
( код буквы А - 410) так что тут есть 2 пути
первое(если не критично) меняй Ё на Е. второе проверяй сам.
например програмно вычесть из кодов букв А-Е единичку и вствить твою Ё
PS а для сторчных ё>я
Автор: nEJIbMEHb3
Дата сообщения: 14.03.2007 10:10
В .NET есть FindAttribute Но мы тут про Дельфи
Автор: vshersh
Дата сообщения: 14.03.2007 10:21
andead
Вставлю свои 5 копеек
Если использование TXMLDocument не критично - предлагаю юзать MSXML-парсер. Там без цикла легко можно получить нужный узел при помощи XPath:

Код: Node := Doc.selectsinglenode('/ProvidersList/provider[@name="sdf" and @id="1"]');
Автор: gogaman
Дата сообщения: 14.03.2007 11:01
Прошу вашей помощи я не силен в программировании и врядли осилю.
Но вот возникла необходимость сделать 2 вещи.
1. Это слепить 2 файла в один ехе сделать форму закинуть 3 кнопки и по нажатию кнопки открывать файлы и закрыть форму. Как закрыть форму уже разобрался. Даже слепил 2 файла в ресурс и присоединил к форме а вот присвоить кнопке вызов файла из ресурса не как лиш удалось просто извлечь и сохранить а хотелось запускать файл из ехе а при его закрытии чтоб он не где не сохранялся.

procedure TForm1.Button1Click(Sender: TObject);
var f1: TResourceStream;
begin
f1 := TResourceStream.Create(hInstance, 'f1', RT_RCDATA);
f1.SaveToFile('1.doc');
f1.Free;
end;

2. Просто указать кнопке запуск файла к примеру в папке лежит 3 файла мне нужно из формы запускать при нажатии кнопки файл.

Заранее благодарен.
Автор: Solnake
Дата сообщения: 14.03.2007 11:04
svs123456789

Цитата:
а ты можешь сделать sql команды без создания объекта типа tdataset ?

Не понял полноты вопроса.
Вам нада связать датасеты. Вопрос - зачем? Если для того чтобы связать запросы в один - SQL. Если для того чтобы визуальные компоненты отображали чето связаное по FK - так можна обойтись без всяких связей этих датасетов. Событий компонентов, сорсов предостаточно.
Опишите что вам именно нада.

Автор: RostY
Дата сообщения: 14.03.2007 11:56
gogaman
Запуск файла -- смотри в сторону ShellExecute
Автор: svs123456789
Дата сообщения: 14.03.2007 12:45
Solnake
спасибо за внимание к вопросу!

таблица T1 (заказы), табл T2 (товары)
связь многие-ко-многим (через табл Т12 - заказано)
в талице t12 есть поля t1_id и t2_id

1) надо при перемещении в гриде заказы T1 отображать в другом гриде соответствующие записи из товары T2
запрос в датасете

Код:
select t2.*
from
Table1 t1, Table2 t2, Table12 t12
where t1.ID = t12.ID_t1 and t2.ID = t12.ID_t2
and t12.ID_Table1 = :ID
Автор: Solnake
Дата сообщения: 14.03.2007 15:40
svs123456789

Делается все елементарно просто.
Датасет №1 в котором заказы отображаются.

Код:
select *
from Table1
Автор: andead
Дата сообщения: 14.03.2007 16:13
vshersh
спасибо! с XPath всё получилось
Автор: dmit000
Дата сообщения: 14.03.2007 17:45
gogaman

//Даже слепил 2 файла в ресурс и присоединил к форме. //

А как это ты сделал?
Приведи пожалуйсто код я тоже хочу так.

//а вот присвоить кнопке вызов файла из ресурса не как лиш удалось просто извлечь и сохранить//

Если извлекается туда куда ты захотел, то можно прописать в программе путь до этих файлов и открывать с помощью ShellExecute, а затем при закрытии формы убивать программно эти файлы


Автор: svs123456789
Дата сообщения: 14.03.2007 18:42
Solnake

Цитата:
на событие ДС2 BeforeOpen присваиваете параметру :ID тот айди на котром стоите в заказах.

Грид и ДС звязываете полюбому через ДатаСорс, в нем есть такое событие как OnDataChange. так вот, на это событие делаете рефреш ДС2 в виде Close, Open.

а зачем постоянно! на OnDataChange переоткрывать запрос
если у датасета есть свойство мастерсоурсе ?


Цитата:
Для того чтобы удалить заказаные товары - пишите запрос который удаляет товары для выбраного заказа. Можна зделать чтобы полностю для заказа удалялись товары, можна просто удалять по ID заказаного, он у вас будет уникальным.

а запрос на удаление выбранного-текущего товара у выбранного заказа
не затруднит помочь написать?
Автор: VadimLou
Дата сообщения: 14.03.2007 22:43
greenpc
more - пытался, но т.к. в тексте есть квадрат скобки - движок сайта ругается ...

Цитата:
2. ф-ции сравнения работают правильно !

врёте батенька ... Нарушение транзитивности налицо. Ошибки наблюдаются при неравентстве сравниваемых строк. Самому что то в строках подменять не катит - т.к. строк много и сильно скажется на скорости... Бяка критичная , т.к. сортировка частично отваливается... Нужно именно подменять мелкософт реализацию ... на свою... Кой чё уже поднарыл в FastCode...
Автор: Solnake
Дата сообщения: 15.03.2007 01:21
svs123456789

Цитата:
если у датасета есть свойство мастерсоурсе ?

1.Да, есть такое дело, но... такой механизм более гибок. Обьяснять почему не буду, так, из личного опыта.
2. Хорошо что у тебя там 1000 записей, и ты будеш локейтится на нужные тебе, но вот у тебя 1000000 записей, и для того чтобы выбрать тебе товары к заказу №245 которых всего 10 штук ты будеш вытягивать все записи, а потом локейтить? Может не все так плачевно как я описал, но этот мастерсорс не видел чтобы использовали в больших проектах. Но дело хозяйское, я подсказываю то как делаю это я.


Цитата:
а запрос на удаление выбранного-текущего товара у выбранного заказа
не затруднит помочь написать?

Пожалусто:

Код: delete from Table12
where
Table12ID=:ID
Автор: gogaman
Дата сообщения: 15.03.2007 10:05
dmit000

Создал файл с расш. rc назвал его 1 в текст редакторе набирал
f1 RCDATA 1.doc
f2 RCDATA 2.doc
и т.д.
Забросил етот файл и 1.doc, 2.doc в папку с компилятор. (brc32.exe, brcc32.exe чем отличаются не знаю) в тотале указываю brc32.exe 1.rc жму ентер и получил файл 1.res

потом добавил сюда

implementation

{$R *.dfm}
{$R 1.res}
Автор: dmit000
Дата сообщения: 15.03.2007 10:56
gogaman
Спасибо большое.
Попробую.

А то что я говорил по поводу считывани и убивания файлов ты пробовал сделать?

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667

Предыдущая тема: Событие STFilter(DBGridEh) ???


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.