Форум программистов, компьютерный форум, киберфорум
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
6 / 6 / 0
Регистрация: 08.03.2020
Сообщений: 62
Записей в блоге: 2
1

Если открыт Excel, то возникает ошибка при сохранении

09.03.2020, 13:42. Показов 2689. Ответов 15

Author24 — интернет-сервис помощи студентам
Здравствуйте!
Если что-то неправильно (не та ветка и т.д.), то я первый раз на форуме.
Пишу программу, работающую с Excel. Сохраняет-загружает нормально, большинство ошибок исправил. Но когда жмёшь кнопку "Сохранить в Excel" и одновременно открыт файл, в который нужно сохранить, то выдаёт ошибку "Project ИМЯ_ТАКОЕ-ТО.exe raised exception class EOleException with message 'Нет доступа к ИМЯ_ТАКОЕ-ТО.xlsx''. Process stopped. Use Step or Run to continue", зелёная стрелка указывает на строку Excel.WorkBooks[1].WorkSheets[1].SaveAs(GetExcelFileName), выделенную синим цветом и Excel остаётся в фоновых процессах Диспетчера задач.

Если без Delphi запускаю из Windows скомпилированный exe-файл и одновременно открыт файл, куда нужно сохранить, тогда тоже выдаёт ошибку 'Нет доступа к ИМЯ_ТАКОЕ-ТО.xlsx'.
Есть ли что-то вроде Excel.DisplayAlerts := False, чтобы перехватить эту ошибку и либо закрыть Excel (необязательно. Пользователь открыл - пусть сам и закрывает), либо вывести вежливый ShowMessage с просьбой закрыть файл вместо ошибки "Нет доступа"?
Помогите, пожалуйста. Уже несколько дней эту проблему ищу. Спасибо!

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

На всякий случай программный код кнопки "Сохранить в Excel":

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
procedure TRiskForm.SaveButtonClick(Sender: TObject);
var
  i, j: Word;
begin
  try
  Excel := CreateOleObject('Excel.Application');
 
    Excel.Visible := false;
    Excel.Workbooks.Add;
    Excel.ActiveWorkbook.Worksheets[1];
 
  with ConditionOfBankStringGrid do
  begin
    for i := 0 to ColCount - 1 do
      for j := 0 to RowCount - 1 do
        Excel.Sheets[1].Cells[j + 1, i + 1] := Cells[i, j];
  end;
    Excel.Sheets[1].Cells[1, 7] := 'Итог:'; {Записываем процент РВКа}
    Excel.Sheets[1].Cells[1, 8] := ProbabilityLabel.Caption;
    Excel.DisplayAlerts := False; // Отключаем все предупреждения Excel
 
    Excel.WorkBooks[1].WorkSheets[1].SaveAs(GetExcelFileName);
    ShowMessage('Сохранено в файл "ConditionOfBank.xlsx"');
  finally
    Excel.Workbooks.Close;  // Закрываем рабочую книгу Excel
    Excel.Quit;             // Закрываем приложение Excel
    Excel := Unassigned;    // Чтобы Excel исчезал из процессов Диспетчера задач
  end;
end;
Добавлено через 19 минут
Многострочные коды пробовал добавлять, но много багов получается. Пожалуйста, попроще, если есть.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.03.2020, 13:42
Ответы с готовыми решениями:

При сохранении xml возникает ошибка, связанная с кодировкой
string str = null; string strRepl = null; StreamReader sr = new...

При сохранении битмапа возникает такая ошибка: "В GDI+ возникла ошибка общего вида"
помогите пожалуйста при сохранении битмапа возникает такая ошибка: "В GDI+ возникла ошибка общего...

Ошибка при сохранении Excel файла
Здравствуйте, помогите пожалуйста решить проблему: С помощью Visual Basic создаю excel файл и...

Ошибка при сохранении данных из StringGrid в Excel
Добрый день! Возникает проблема при попытке сохранения данных из StringGrid в формате Excel ...

15
Модератор
9457 / 6210 / 2420
Регистрация: 21.01.2014
Сообщений: 26,472
Записей в блоге: 3
09.03.2020, 15:14 2
А как, интересно, Вы хотите записать данные в файл, уже открытый на редактирование? Такой фокус не пройдет, если только сама книга Excel не настроена на многопользовательский режим... Ищите открытые процессы Excel, проверяйте на соответствие открытый файл и свое имя и если совпадает - либо сами убивайте процесс либо просите сделать это пользователя...
Но вообще - это не есть гут - лезть программно в файл, куда могут залезть другие пользователи... Очень много косяков можно огрести...
0
6 / 6 / 0
Регистрация: 08.03.2020
Сообщений: 62
Записей в блоге: 2
09.03.2020, 15:49  [ТС] 3
записать данные в файл, уже открытый на редактирование, я не хочу. Я как раз ищу вариант "либо сами убивайте процесс либо просите сделать это пользователя".
Видимо, подобный вопрос рассмотрен в теме Проверить открыт ли файл excel, если да закрыть, но мне не удалось это применить, не всё понятно (я не программист по образованию).
0
Модератор
9457 / 6210 / 2420
Регистрация: 21.01.2014
Сообщений: 26,472
Записей в блоге: 3
09.03.2020, 16:21 4
Цитата Сообщение от Alexander-7 Посмотреть сообщение
Видимо, подобный вопрос рассмотрен в теме
Именно он и рассмотрен...
Цитата Сообщение от Alexander-7 Посмотреть сообщение
не всё понятно
учите мат. часть
Цитата Сообщение от Alexander-7 Посмотреть сообщение
я не программист по образованию
я тоже.
1
6 / 6 / 0
Регистрация: 08.03.2020
Сообщений: 62
Записей в блоге: 2
09.03.2020, 16:27  [ТС] 5
Понятно, спасибо!
0
Модератор
9457 / 6210 / 2420
Регистрация: 21.01.2014
Сообщений: 26,472
Записей в блоге: 3
09.03.2020, 16:31 6
Alexander-7, я еще раз не постесняюсь спросить: почему файл, куда Вы что-то пытаетесь писать программно, должен быть открыт каким-то левым пользователем? Что за глобальная задача перед Вами поставлена?
0
6 / 6 / 0
Регистрация: 08.03.2020
Сообщений: 62
Записей в блоге: 2
10.03.2020, 13:39  [ТС] 7
D1973, например, поработал пользователь в написанной мной программе. Потом нажал "Сохранить" и программа сама создала файл Excel. Он заинтересовался, что это за файл появился, открыл его. Забыл закрыть (или не знает, что надо закрыть), переключился на программу, что-то изменил и опять захотел сохранить. Так вот надо, чтобы вместо ошибки "Нет доступа к ..." вышло заготовленное сообщение: "Закройте, пожалуйста ...".
Я много вариантов перепробовал. Уже устал с этим вопросом. Буду благодарен, если кто подскажет конкретную строчку (или 2-3), но не "многоэтажные" процедуры, которые в ссылке выше: пока что я не спец в Delphi. Если такого нет, то извиняюсь за беспокойство.

Цитата Сообщение от D1973 Посмотреть сообщение
Ищите открытые процессы Excel, проверяйте на соответствие открытый файл и свое имя и если совпадает
Наверное, так и надо, но как это выглядит на языке Delphi? Отследить, открыт ли файл Excel можно ли в 1-2 строки? Если открыт, то попросить закрыть, иначе выполнить SaveAs.

Добавлено через 27 минут
Цитата Сообщение от D1973 Посмотреть сообщение
Что за глобальная задача перед Вами поставлена?
Разработка системы противодействия Skynet'у
0
5485 / 4400 / 1076
Регистрация: 29.08.2013
Сообщений: 27,569
Записей в блоге: 3
10.03.2020, 13:42 8
Цитата Сообщение от Alexander-7 Посмотреть сообщение
Я много вариантов перепробовал.
а поискать?
Проверить открыт ли файл excel, если да закрыть

то есть если в решении больше 3х строк, то ты им не воспользуешься?
как же ты будешь программы писать?
0
6 / 6 / 0
Регистрация: 08.03.2020
Сообщений: 62
Записей в блоге: 2
10.03.2020, 14:15  [ТС] 9
qwertehok, именно эту ссылку я сам привёл Выше. Можно и больше 3-х строк.
0
5485 / 4400 / 1076
Регистрация: 29.08.2013
Сообщений: 27,569
Записей в блоге: 3
10.03.2020, 15:04 10
но там же прямо функция написана по проверке
0
6 / 6 / 0
Регистрация: 08.03.2020
Сообщений: 62
Записей в блоге: 2
15.03.2020, 16:05  [ТС] 11
Решение найдено. Сделал через SaveDialog и OpenDialog. Вероятность подключения к запущенному excel отлавливаю через try-except. По крайней мере, ошибку не выдаёт. Как-то так:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
    ShowMessage('Для корректного сохранения закройте все окна Excel');
    if SaveDialog.Execute then begin // Если запустили окно сохранения, то...
    try
      { Ищем запущенный экземпляр Excel, если не найден, вызываем исключение }
      { Чтобы не было системной ошибки "Нет доступа" }
      Excel := GetActiveOleObject('Excel.Application');
      Excel.DisplayAlerts := False; // Отключаем предупреждение Excel о замене
    except
    end;
      Excel.ActiveWorkbook.SaveAs(SaveDialog.FileName);
      ShowMessage('Сохранено в файл:' + #10 + SaveDialog.FileName);
    end;
Добавлено через 2 минуты
После этого SaveAs, finally и т.д.
0
5485 / 4400 / 1076
Регистрация: 29.08.2013
Сообщений: 27,569
Записей в блоге: 3
15.03.2020, 16:26 12
Цитата Сообщение от Alexander-7 Посмотреть сообщение
ошибку не выдаёт
так у тебя блок except не обрабатывается, поэтому и не выдает
0
6 / 6 / 0
Регистрация: 08.03.2020
Сообщений: 62
Записей в блоге: 2
16.03.2020, 14:36  [ТС] 13
qwertehok, это хорошо или плохо? Пустой except я нашёл на . Сам Excel остаётся в фоновых процессах.
И ещё. Что такое VarIsEmpty(Excel) доступными словами? Что означает, когда оно = true и когда = false?

Добавлено через 55 секунд
- здесь Пустой except

Добавлено через 1 минуту
Ссылки на чужие форумы запрещены? В общем нашёл где-то.
0
5485 / 4400 / 1076
Регистрация: 29.08.2013
Сообщений: 27,569
Записей в блоге: 3
16.03.2020, 14:39 14
Цитата Сообщение от Alexander-7 Посмотреть сообщение
это хорошо или плохо?
это странно, ошибка есть, но ты ее не показываешь и не обрабатываешь

Цитата Сообщение от Alexander-7 Посмотреть сообщение
Сам Excel остаётся в фоновых процессах.
а если 10 раз отредактировать и сохранить? будет 10 экселей?
0
6 / 6 / 0
Регистрация: 08.03.2020
Сообщений: 62
Записей в блоге: 2
02.04.2020, 16:08  [ТС] 15
Решение я всё-таки нашёл. Ларчик просто открывался. Чтобы тема не «висела» без ответа, завершу – может ещё кому-то пригодится:

1. Заключить SaveAs в try-except.
Delphi
1
2
3
4
5
6
7
    try  
      Excel.ActiveWorkbook.SaveAs(SaveDialog.FileName);
      ShowMessage('Сохранено в файл:' + #10 + SaveDialog.FileName);
    except
      ShowMessage('Невозможно сохранить в этот файл, он занят или доступен только для чтения.'
      + #10 + 'Выберите другое имя');
    end;
Это ещё половина решения. Ошибка продолжает вылетать. Далее

2. Отключить реакцию системы Delphi на исключительные ситуации, тем самым давая возможность отработать операторам try/except/end. Пункт системного меню Delphi Tools -> Debugger Options. В появившемся окошке нужно снять галку в чекбоксе Stop on Delphi Exceptions, расположенном на вкладке Language Exceptions.

Также потом советуют вернуть эту галочку. Теперь всё чётко работает.
0
5485 / 4400 / 1076
Регистрация: 29.08.2013
Сообщений: 27,569
Записей в блоге: 3
02.04.2020, 16:45 16
Цитата Сообщение от Alexander-7 Посмотреть сообщение
Решение я всё-таки нашёл.
это костыль, причем если раньше ты не обрабатывал исключения, теперь ты их отключил

код, который тебе дали выше, проверяет не открыт ли файл и прекрасно работает
0
02.04.2020, 16:45
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.04.2020, 16:45
Помогаю со студенческими работами здесь

Ошибка при сохранении dataGridView в Excel файл.
Хочу сохранить датугридвью в эксель файл. Выдает следующую ошибку. Может я забыл подгрузить...

Ошибка при сохранении после чтения-записи в Excel
Добрый день! Имеется две кнопки, одна для записи в эксель, другая для чтения оттуда (используя...

Возникает ошибка при записи в файл Excel
При написания кода в Delphi ( приведенного ниже) компиляция происходит нормально, без ошибок. Но...

При сохранении данных таблицы StringGrid в Excel появляется ошибка
При сохранении данных таблицы StringGrid в Excel появляется ошибка. Код пишу в обработчике кнопки...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru