С Новым годом! Форум программистов, компьютерный форум, киберфорум
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
 Аватар для Alexander-7
8 / 8 / 0
Регистрация: 08.03.2020
Сообщений: 64
Записей в блоге: 5

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

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

Студворк — интернет-сервис помощи студентам
Здравствуйте!
Если что-то неправильно (не та ветка и т.д.), то я первый раз на форуме.
Пишу программу, работающую с 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
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.03.2020, 13:42
Ответы с готовыми решениями:

При сохранении xml возникает ошибка, связанная с кодировкой
string str = null; string strRepl = null; StreamReader sr = new StreamReader(@"C:\ParserHTML\sample.xml"); while (!sr.EndOfStream) ...

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

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

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

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

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

то есть если в решении больше 3х строк, то ты им не воспользуешься?
как же ты будешь программы писать?
0
 Аватар для Alexander-7
8 / 8 / 0
Регистрация: 08.03.2020
Сообщений: 64
Записей в блоге: 5
10.03.2020, 14:15  [ТС]
qwertehok, именно эту ссылку я сам привёл Выше. Можно и больше 3-х строк.
0
5954 / 4530 / 1094
Регистрация: 29.08.2013
Сообщений: 28,123
Записей в блоге: 3
10.03.2020, 15:04
но там же прямо функция написана по проверке
0
 Аватар для Alexander-7
8 / 8 / 0
Регистрация: 08.03.2020
Сообщений: 64
Записей в блоге: 5
15.03.2020, 16:05  [ТС]
Решение найдено. Сделал через 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
5954 / 4530 / 1094
Регистрация: 29.08.2013
Сообщений: 28,123
Записей в блоге: 3
15.03.2020, 16:26
Цитата Сообщение от Alexander-7 Посмотреть сообщение
ошибку не выдаёт
так у тебя блок except не обрабатывается, поэтому и не выдает
0
 Аватар для Alexander-7
8 / 8 / 0
Регистрация: 08.03.2020
Сообщений: 64
Записей в блоге: 5
16.03.2020, 14:36  [ТС]
qwertehok, это хорошо или плохо? Пустой except я нашёл на . Сам Excel остаётся в фоновых процессах.
И ещё. Что такое VarIsEmpty(Excel) доступными словами? Что означает, когда оно = true и когда = false?

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

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

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

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
5954 / 4530 / 1094
Регистрация: 29.08.2013
Сообщений: 28,123
Записей в блоге: 3
02.04.2020, 16:45
Цитата Сообщение от Alexander-7 Посмотреть сообщение
Решение я всё-таки нашёл.
это костыль, причем если раньше ты не обрабатывал исключения, теперь ты их отключил

код, который тебе дали выше, проверяет не открыт ли файл и прекрасно работает
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
02.04.2020, 16:45
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru