Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 2 848

Раздел: Delphi » Прочее
/ вопрос открыт /

Доброго времени суток, уважаемые эксперты!
У меня в цикле есть try except, если выпадает исключительная ситуация то весь цикл прерывается,
Вопрос как сделать чтобы (прерывался, пропускался) только один цикл?
goto из оператора try except не работает, выдаёт [DCC Error] test.pas(172): E2127 'GOTO Lbegin' leads into or out of TRY statement

Приложение:
  1. for K := 0 to ListBox1.Items.Count - 1 do
  2. try
  3. lll:= TFileStream.Create ('LandocsIniFileName',fmCreate or fmOpenWrite or fmShareExclusive);
  4. except
  5. ListBox2.Font.Color := (clRed);
  6.  
  7. ListBox2.Font.Color := (clBlack);
  8. goto Lbegin;
  9. end;
  10. lll.Free;
  11. LandocsIniFile := TIniFile.Create(LandocsIniFileName);
  12. Lbegin:
  13. end;


slava863 Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: slava863 (статус: Посетитель)
Вопрос отправлен: 27 мая 2009, 11:54
Состояние вопроса: открыт, ответов: 2.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, slava863!
Правильно, потому что нельзя использовать goto для выхода за пределы блока except. Да и можно без него обходиться.
для этой цели придумали Continue - завершить текущую интерацию цикла и перейти к следующей. Также надо знать, что есть ещё break - завершить цикл досрочно.
Эти два "псевдооператора" позволяют избегать использования goto. Они работают не только для for, а и для while и repeat-until.
У них есть один недостаток - они позволяют управлять только тем циклом, в который вложены.

P.S. в коде есть утечка памяти - объект lll надо удалять даже есть не удалось открыть файл.

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 27 мая 2009, 12:16
Оценка за ответ: 5

Комментарий к оценке: спасибо про Continue я как-то не нашел.

Ответ #2. Отвечает эксперт: min@y™

for K := 0 to ListBox1.Items.Count - 1 do
  try
    lll:= TFileStream.Create ('LandocsIniFileName',fmCreate or fmOpenWrite or fmShareExclusive);
  except
    ListBox2.Font.Color := (clRed); // <--- здесь меняется шрифт во всём листбоксе, а не только в строке, которую
добавляешь
    ListBox2.Items.add (LandocsIniFileName + '   - Не могу записать');
    ListBox2.Font.Color := (clBlack); // <--- здесь тоже
    goto Lbegin;
  end;
 
  lll.Free;
  LandocsIniFile := TIniFile.Create(LandocsIniFileName);
  Lbegin:
end;

Я вообще с трудом понимаю, для чего нужен такой код. Ты хочешь проверить, доступен ли твой ini-файл для чтения/записи? Тогда не занимайся ерундой с TFileStream – он здесь не нужен. Объясни по-человечески, что же тебе в конце концов нужно?

Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 27 мая 2009, 20:23


Мини-форум вопроса

Всего сообщений: 12; последнее сообщение — 12 июня 2009, 10:53; участников в обсуждении: 3.
slava863

slava863 (статус: Посетитель), 28 мая 2009, 09:14 [#1]:

хочу проверить если ini файл занят или недоступен, то вывести запись в listbox и прервать текущую интерацию цикла и перейти к следующей.

И может подскажите как сделать listbox горизонтальную прокрутку?
min@y™

min@y™ (статус: Доктор наук), 28 мая 2009, 13:36 [#2]:

Цитата:


хочу проверить если ini файл занят или недоступен, то вывести запись в listbox и прервать текущую интерацию цикла и перейти к следующей.


Пусть у тебя есть несколько ini-файлов, имена которых находятся в ListBox. C этими файлами тебе нужно поработать, т.е. как-то обработать каждый файл, а в случае ошибки ввода/вывода/доступа вывести сообщение в ListBox напротив имени файла, при работе с которым возникло исключение.

Вот то, что я выделил красным жирным шрифтом - это тебе пример, как надо правильно задавать вопросы, чтобы получать быстрые и чёткие ответы. А то нам тут приходится заниматься дешифровкой и телепатией.

// Заготовка функции обработки группы ini-файлов,
// имена которых содержатся в списке AFileList.
// Возвращаемое значение - кол-во безошибочно обработанных файлов.
function ProcessIniFiles(AFileList: TStrings): Integer;
var
  Index: Integer;
  Ini: TIniFile;
begin
  Result:= 0;
 
  for Index:= 0 to AFileList.Count - 1 do
    begin
      try
        Ini:= TIniFile.Create(AFileList[Index]);
        try
          // <--- здесь работа с текущим файлом (чтение/запись)
        finally
          FreeAndNil(Ini);
        end;
 
        Inc(Result);
      except
        AFileList[Index]:= AFileList[Index] + ' - Ошибка при работе с файлом.';
      end;
    end;
end;
 
// Пример вызова функции:
Count:= ProcessIniFiles(ListBox.Items);
if Count <> ListBox.Count
  then ShowMessage('Обработаны не все файлы!');

==============================================

Горизонтальная прокрутка в ListBox - это классика.
Вот у меня тут книжка перед глазами, там такой пример есть, могу прислать.

Цитата из книжки:

Цитата:


Компонент TListBox библиотеки VCL в Object Pascal является оболочкой стандартного элемента управления Win32 API LISTBOX. Совершенству нет предела, поэтому, хотя компонент TListBox инкапсулирует большую часть функциональности элемента Win32, все же попытаемся его расширить. В этом разделе мы проанализируем шаг за шагом процесс создания пользовательского компонента на базе компонента TListBox.

Идея

Идея создания нового компонента, как часто бывает, подсказана практикой. Однажды потребовался список с использованием позиций табуляции и горизонтальной полосы прокрутки для чтения строк, оказавшихся длиннее ширины списка. Обе эти возможности поддерживаются интерфейсом Win32 API, но не реализованы в компоненте TListBox. Назовем новый компонент TddgTabListbox.


Также, в пакете RxLib есть готовый компонент TTextListBox/ Цитата из хэлпа RxLib:

Цитата:


Компонента TTextListBox предназначена для организации списков текстовых строк на основе стандартного элемента управления Windows (ListBox), и позволяет пользователю осуществить выбор одного или более элементов из этого списка.
В отличие от компоненты TListBox, TTextListBox предназначен только для текстовых строк, но он автоматически устанавливает горизонтальную полосу прокрутки при изменении содержимого свойства Items.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
slava863

slava863 (статус: Посетитель), 29 мая 2009, 11:30 [#3]:

а название книжки можно, может найду в электронном виде.
min@y™

min@y™ (статус: Доктор наук), 29 мая 2009, 11:41 [#4]:

Да вот она, качай на здоровье.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
slava863

slava863 (статус: Посетитель), 9 июня 2009, 16:32 [#5]:

не могу понять почему не работает.
если InsertIniFileName:= ('')имя файла пустое,TIniFile.Create всё равно делает вид что открывает

try
InsertIniFile := TIniFile.Create(InsertIniFileName);
ShowMessage('файл с изменениями: ' + InsertIniFileName);
except
ShowMessage('Не могу открыть файл с изменениями: ' + InsertIniFileName);
end;

Мне нужно:
есть ini файл, его нужно открыть для чтения.
и проверить если не выбрано имя файла (пустое), или невозможно открыть файл выдавалось сообщение.
Вадим К

Вадим К (статус: Академик), 9 июня 2009, 16:40 [#6]:

а потому что если файл нельзя открыть, то ошибка появиться только при попытке сохранить (то есть закрыть ини файл). Так он устроен. Не нравиться - пишите свой парсер ини файлов, это не сложно.
Галочка "подтверждения прочтения" - вселенское зло.
min@y™

min@y™ (статус: Доктор наук), 9 июня 2009, 17:29 [#7]:

try
  if not FileExists(InsertIniFileName) // проверка существования файла
    then raise;
 
  InsertIniFile := TIniFile.Create(InsertIniFileName);
  ShowMessage('файл с изменениями: ' + InsertIniFileName);
except
  ShowMessage('Не могу открыть файл с изменениями: ' + InsertIniFileName);
end;
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Вадим К

Вадим К (статус: Академик), 9 июня 2009, 17:35 [#8]:

to min@y™
А если файл будет занят на запись (или доступен только на чтение), то окрыть, откроет, а вот сохранить - не сможет. Это кстати причина того, что некоторые программы при запуске с компакта и хранящие конфиги "рядом" не могут сохранять настройки.
Галочка "подтверждения прочтения" - вселенское зло.
min@y™

min@y™ (статус: Доктор наук), 9 июня 2009, 17:48 [#9]:

Цитата (Вадим К):

А если файл будет занят на запись (или доступен только на чтение), то окрыть, откроет, а вот сохранить - не сможет. Это кстати причина того, что некоторые программы при запуске с компакта и хранящие конфиги "рядом" не могут сохранять настройки.

Всё правильно, я так и написал код в своём посте выше (28 мая). Там вся работа с ini, включая его убиение, находится внутри try ... except.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
slava863

slava863 (статус: Посетитель), 9 июня 2009, 17:58 [#10]:

спасибо
slava863

slava863 (статус: Посетитель), 12 июня 2009, 10:23 [#11]:

Ещё вопрос:
вот функция получения сетевого имени компьютера, а как получить список в ListBox всех компов в сети?

function GetComputerNetName: string;//получение имени компа
var
buffer: array[0..255] of char;
size: dword;
begin
size := 256;
if GetComputerName(buffer, size) then
Result := buffer
else
Result := ''
end;
min@y™

min@y™ (статус: Доктор наук), 12 июня 2009, 10:53 [#12]:

Оффтопик. Задай вопрос.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:58
Выполнено за 0.03 сек.