Excel 창 열기로 인해 C#에서 Excel로 데이터 쓰기가 중단됨
C# 프로그램이 Excel 스프레드시트에 계속 데이터를 쓰는 동안 최종 사용자가 오른쪽 상단 메뉴를 클릭하고 Excel 옵션 창을 열면 다음과 같은 예외가 발생합니다.
시스템. 런타임.Interop Services.HRESULT를 포함한 COME 예외: 0x800AC472
그러면 데이터가 스프레드시트에 기록되는 것이 중단됩니다.
이상적으로 사용자는 예외 없이 이 작업을 수행할 수 있어야 합니다.
이 오류 코드에 대한 유일한 해결책은 예외가 사라질 때까지 루프하고 기다리는 것이었습니다: HRESULT에서 예외: 0x800AC472는 앱을 효과적으로 중단시키고 데이터는 Excel에 기록되지 않으며 사용자는 문제에 대해 알지 못합니다.
엑셀에 글을 쓰면서 메인 메뉴를 비활성화할까 생각했는데, 어떻게 하는지 참고 자료를 찾을 수가 없습니다.
내 앱은 Excel 2000부터 2013까지 지원합니다.
문제를 재현하는 방법은 다음과 같습니다.
윈도우즈 데스크톱용 Visual Studio Express 2013 사용,윈도우즈 7 64비트에서 NET 4.5.1(Excel 2007 포함), 새 Visual C# 콘솔 응용 프로그램 프로젝트를 생성합니다.
"Microsoft Excel 12.0 Object Library"(Excel의 경우) 및 "System"에 대한 참조를 추가합니다.창문들.양식"(메시지 상자용).
전체 코드는 다음과 같습니다.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading.Tasks; using System.Threading; // for sleep using System.IO; using System.Runtime.InteropServices; using System.Reflection; using Microsoft.Win32; using Excel = Microsoft.Office.Interop.Excel; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { int i = 3; // there is a split pane at row two Excel.Application xlApp; Excel.Workbook xlWorkBook; Excel.Worksheet xlWorkSheet; try { object misValue = System.Reflection.Missing.Value; xlApp = new Excel.Application(); xlApp.Visible = false; xlWorkBook = xlApp.Workbooks.Add(misValue); xlApp.Visible = true; xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); // next 2 lines for split pane in Excel: xlWorkSheet.Application.ActiveWindow.SplitRow = 2; xlWorkSheet.Application.ActiveWindow.FreezePanes = true; xlWorkSheet.Cells[1, 1] = "Now open the"; xlWorkSheet.Cells[2, 1] = "Excel Options window"; } catch (System.Runtime.InteropServices.COMException) { System.Windows.Forms.MessageBox.Show("Microsoft Excel does not seem to be installed on this computer any longer (although there are still registry entries for it). Please save to a .tem file. (1)"); return; } catch (Exception) { System.Windows.Forms.MessageBox.Show("Microsoft Excel does not seem to be installed on this computer any longer (although there are still registry entries for it). Please save to a .tem file. (2)"); return; } while(i < 65000) { i++; try { xlWorkSheet.Cells[i, 1] = i.ToString(); Thread.Sleep(1000); } catch (System.Runtime.InteropServices.COMException) { System.Windows.Forms.MessageBox.Show("All right, what do I do here?"); } catch (Exception) { System.Windows.Forms.MessageBox.Show("Something else happened."); } } Console.ReadLine(); //Pause } } }앱을 랜치하면 Excel이 나타나고 데이터가 작성됩니다.메뉴에서 Excel 옵션 대화창을 열면 다음 오류가 나타납니다.
입니다.System' 유형의 예외입니다. 운용 서비스입니다Interop 서비스.'했으며 관리 'COMEXception'의 mscorlib 이전에 .dll에서 발생했으며 관리/원본 경계 이전에 처리되지 않았습니다.
: HRESULT에서 HRESULT 파일: 0x800AC472계속을 클릭하면 "좋아요, 여기서 뭘 해야 하나요?"라는 메시지 상자가 나타납니다.
조언 부탁드립니다.
베르트랑, 잘 부탁드립니다.
이 문제를 해결하기 위해 마이크로소프트 지원 서비스를 시작했습니다.이들의 최종 반응은 다음과 같습니다.
저는 그 문제를 재현할 수 있습니다.저는 이것에 대해 더 연구했고 이 행동이 의도적으로 기대된다는 것을 발견했습니다.예외: 0x800AC472 – VBA_E_IGNORE는 Excel이 사용 중이고 Object Model 호출을 처리하지 않기 때문에 느려집니다.여기 이것에 대해 이야기하는 토론 중 하나가 있습니다.http://social.msdn.microsoft.com/Forums/vstudio/en-US/9168f9f2-e5bc-4535-8d7d-4e374ab8ff09/hresult-800ac472-from-set-operations-in-excel?forum=vsto 제가 볼 수 있는 해결 방법은 이 예외를 명시적으로 포착하고 의도한 작업이 완료될 때까지 잠시 후에 다시 시도하는 것입니다.
소프트웨어가 로깅을 중지했다는 사실을 깨닫지 못하고 창을 열거나 메모를 하기로 결정한 사용자의 마음을 읽을 수 없기 때문에(오류를 마스크한 경우), 다음을 사용하여 해결하기로 결정했습니다.
xlWorkSheet.EnableSelection = Microsoft.Office.Interop.Excel.XlEnableSelection.xlNoSelection;
Excel 창 UI를 잠급니다.명백한 "잠금 해제" 버튼을 제공하지만 사용자가 이 버튼을 클릭하면 메시지 상자에 "계속하시겠습니까?"라는 경고가 표시됩니다.
Make Excel Interactive는 완벽한 솔루션입니다.유일한 문제는 사용자가 Excel에서 범위 선택이나 셀 편집과 같은 작업을 동시에 수행하는 경우입니다.예를 들어 코드가 다른 스레드에서 반환되어 계산 결과를 Excel에 기록하려고 합니다.이 문제를 피하기 위해 제가 제안하는 것은 다음과 같습니다.
private void x(string str)
{
while (this.Application.Interactive == true)
{
// If Excel is currently busy, try until go thru
SetAppInactive();
}
// now writing the data is protected from any user interaption
try
{
for (int i = 1; i < 2000; i++)
{
sh.Cells[i, 1].Value2 = str;
}
}
finally
{
// don't forget to turn it on again
this.Application.Interactive = true;
}
}
private void SetAppInactive()
{
try
{
this.Application.Interactive = false;
}
catch
{
}
}
xlApp = new Excel.Application();
xlApp.Interactive = false;
제가 성공적으로 한 일은 코드로 열기 전에 타겟 엑셀 파일의 임시 복사본을 만드는 것입니다.
그러면 원본 문서가 열려 있는지 여부와 관계없이 문서를 조작할 수 있습니다.
Excel을 자동화하고 Excel의 특이점과 씨름하는 방법 중 하나는 OpenXmlWriter(DocumentFormat)를 사용하여 파일을 쓰는 것입니다.OpenXml.OpenXmlWriter).
그것은 조금 까다롭지만 100만 줄 이상의 시트를 땀 한 방울 흘리지 않고 처리합니다.
Interop은 크로스 스레드를 수행하기 때문에 여러 스레드에 의해 동일한 객체에 액세스할 수 있으며, 아래 코드가 작동하는 예외로 이어질 수 있습니다.
bool failed = false;
do
{
try
{
// Call goes here
failed = false;
}
catch (System.Runtime.InteropServices.COMException e)
{
failed = true;
}
System.Threading.Thread.Sleep(10);
} while (failed);
언급URL : https://stackoverflow.com/questions/23808057/writing-data-from-c-sharp-to-excel-interrupted-by-opening-excel-window
'programing' 카테고리의 다른 글
| jQuery를 사용하여 JSON에서 빈 배열 개체를 테스트하는 중 (0) | 2023.09.04 |
|---|---|
| 파워셸에서 파이썬을 사용하려고 합니다. (0) | 2023.09.04 |
| 성공적으로 실행하기 위해 동등한 mysqli 준비 문을 가져올 수 없습니까? (0) | 2023.09.04 |
| Apache POI를 사용하여 Excel에 파일 포함 (0) | 2023.08.30 |
| VBA를 사용한 Excel 유효성 검사 드롭다운 목록 (0) | 2023.08.30 |