블로그 이미지
안녕1999

카테고리

전체 (3067)
자바스크립트 (20)
안드로이드 (14)
WebGL (4)
변비 (17)
정치,경제 (35)
C언어,ARM (162)
컴퓨터(PC, Note Book, 윈.. (41)
전자회로, PCB (27)
유머,안웃긴,GIF,동영상 (118)
국부론60 (71)
모듈(PCB) (3)
건강 (2)
FreeCAD (25)
PADS (43)
퇴직,퇴사,구직,취업 활동 (3)
C# (86)
엑셀 (8)
워드 (0)
LabView (6)
레고 (30)
FPGA (0)
Total
Today
Yesterday

달력

« » 2024.12
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 30 31

공지사항

최근에 올라온 글

ClassExcel

C# / 2020. 10. 10. 23:42
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Reflection;
using System.IO.Ports;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
/*
https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/interop/how-to-access-office-onterop-objects
https://docs.microsoft.com/ko-kr/previous-versions/office/troubleshoot/office-developer/automate-excel-from-visual-c
https://stackoverflow.com/questions/19543279/microsoft-office-interop-excel-reference-cannot-be-found
Project menu->Add Reference(참조)->COM->Microsoft Excel Object Library


"Microsoft.Office.Interop.Excel not found"
도구 > NuGet 패키지 관리자 > 패키지 관리자 콘솔
Install-Package Microsoft.Office.Interop.Excel


"Microsoft.CSharp.RuntimeBinder.Binder.Convert' 멤버가 필요한 컴파일러가 없습니다
Project menu->Add Reference(참조)->어셈블리->Microsoft.CSharp.dll
*/

public class ClassExcel
{
	Excel.Application excelApp;
	Excel._Workbook wb;
	Excel._Worksheet ws;
	Excel.Range oRng;
	public string m_File;
	bool m_bSaved;

	public ClassExcel()
	{
		excelApp = null;
		wb = null;
		ws = null;
		oRng = null;
		m_bSaved = true;
	}
	~ClassExcel()
	{
		Close();
	}
	void On_err(Exception theException)
	{
		String errorMessage;
		errorMessage = "Error: ";
		errorMessage = String.Concat(errorMessage, theException.Message);
		errorMessage = String.Concat(errorMessage, "\r\n\r\nLine: ");
		errorMessage = String.Concat(errorMessage, theException.Source);

		MessageBox.Show(errorMessage, "Error");
	}
	public bool New(string file, bool Visible = true, bool UserControl = true)
	{
		bool ret = false;
		m_File = file;
		try
		{
			//Start Excel and get Application object.
			excelApp = new Excel.Application();

			excelApp.Visible = Visible;
			excelApp.UserControl = UserControl;

			//Get a new workbook.
			wb = (Excel._Workbook)(excelApp.Workbooks.Add(Missing.Value));
			ws = (Excel._Worksheet)wb.ActiveSheet;

			m_bSaved = false;
			ret = true;
		}
		catch (Exception theException)
		{
			On_err(theException);
		}
		return ret;
	}
	public bool Open(string file, bool Visible = true, bool UserControl = true)
	{
		bool ret = false;
		m_File = G.MakeFullPath(file);
		try
		{
			//Start Excel and get Application object.
			excelApp = new Excel.Application();

			excelApp.Visible = Visible;
			excelApp.UserControl = UserControl;

			// 엑셀 파일 열기
			wb = excelApp.Workbooks.Open(m_File);
			// 첫번째 Worksheet
			ws = wb.Worksheets.get_Item(1) as Excel.Worksheet;

			ret = true;
		}
		catch (Exception theException)
		{
			//open err
			On_err(theException);
		}
		return ret;
	}
	public bool SelectWorksheet(string name)
	{
		bool ret = false;
		int i;
		if (ws.Name != name)
		{
			Excel._Worksheet w;
			for (i = 1; i <= wb.Worksheets.Count; i++)
			{
				w = wb.Worksheets.get_Item(i);// as Excel.Worksheet;
				if (w != null)
				{
					if (w.Name == name)
					{
						w.Activate();
						ws = w;
						ret = true;
						break;
					}
					else
					{ }
				}
				else
				{ }
			}
			if (ret == false)
			{
				//동일한 이름의 시트가 없다. 새로생성
				ws = wb.Worksheets.Add();
				ws.Activate();
				ws.Name = name;
				m_bSaved = false;
				ret = true;
			}
			else
			{ }
		}
		else
		{
			//이미선택됨
		}
		return ret;
	}
	public bool SelectWorksheet(int no1)
	{
		bool ret = false;
		if ((1 <= no1) && (no1 <= wb.Worksheets.Count))
		{
			ws = wb.Worksheets.get_Item(1) as Excel.Worksheet;
			ret = true;
		}
		return ret;
	}
	public void Show(bool bShow)
	{
		excelApp.Visible = bShow;
	}
	public bool Puts(int row1,int col1,string s)
	{
		bool ret = false;
		try
		{
			ws.Cells[row1, col1] = s;
			m_bSaved = false;
		}
		catch
		{
		}
		return ret;
	}
	public bool Puts(string cell, string s)//cell="A2"
	{
		bool ret = false;
		try
		{
			Excel.Range c = ws.get_Range(cell, cell);
			c.Cells[1,1] = s;
			m_bSaved = false;
		}
		catch
		{
		}
		return ret;
	}
	public void SaveAs(string file)
	{
		m_File = file;
		m_bSaved = false;
		Save();
	}
	public void Save()
	{
		try
		{
			if (m_bSaved == false)
			{
				wb.SaveAs(m_File);
			}
			else
			{ }
			m_bSaved = true;
		}
		catch (Exception theException)
		{
			On_err(theException);
		}
	}
	public void Close()
	{
		if (excelApp != null)
		{
			Save();
			try
			{
				wb.Close();
				excelApp.Quit();
				ReleaseExcelObject(excelApp);
				ReleaseExcelObject(wb);
				ReleaseExcelObject(ws);
				excelApp = null;
				wb = null;
				ws = null;
			}
			catch (Exception theException)
			{
				On_err(theException);
			}
		}
		else
		{ }
	}
	private static void ReleaseExcelObject(object obj)
	{
		try
		{
			if (obj != null)
			{
				Marshal.ReleaseComObject(obj);
				obj = null;
			}
		}
		catch (Exception ex)
		{
			obj = null;
			throw ex;
		}
		finally
		{
			GC.Collect();
		}
	}
}

'C#' 카테고리의 다른 글

Form 자식창이 부모창의 중앙에 위치  (0) 2020.10.10
Ini File class  (0) 2020.10.10
리스트뷰 헤더 컬럼들이 안보이는 경우  (0) 2020.10.10
FIFO, GUI 쓰레드 엑세스위반 다른 대안  (0) 2020.10.10
함수 포인터 전달  (0) 2020.10.10
Posted by 안녕1999
, |
		void ListView_new()
		{
			//ListView.ColumnHeaderCollection h = ListView1.Columns;
			ListView1.FullRowSelect = true;
			ListView1.GridLines = true;
			ListView1.View = View.Details;//리스트 헤더 컬럼들이 안보이는 경우, 이 항목을 안넣어서 그럴 수 도 있다.
			ListView1.Columns.Add("sheet", 10);
			ListView1.Columns.Add("cell", 10);
			ListView1.Columns.Add("text", 500);
			ListView1.Columns.Add("min", 50, HorizontalAlignment.Center);
			ListView1.Columns.Add("value", 50, HorizontalAlignment.Center);
			ListView1.Columns.Add("max", 50, HorizontalAlignment.Center);
		}

'C#' 카테고리의 다른 글

Ini File class  (0) 2020.10.10
ClassExcel  (0) 2020.10.10
FIFO, GUI 쓰레드 엑세스위반 다른 대안  (0) 2020.10.10
함수 포인터 전달  (0) 2020.10.10
Form 사이즈 변경  (0) 2020.10.10
Posted by 안녕1999
, |
쓰레드에서 GUI함수를 호출하면 (거의 대부분) 에러가 발생할 수 있다.
이럴때 Invoke등을 사용해서 처리하나, 여기서는 다른 방법을 제시해본다.

쓰레드가 처리해야할 함수의 파라메터값들을 GUI쓰레드로 보내고,
GUI쓰레드의 타이머에서 처리하도록 하는것이다.
데이터 전달은 FIFO를 사용하고,
FIFO의 데이터는 구조체를 사용했다.(범용성있게 수정이 필요하다. 예)인덱스 사용)

장점 : 
- Invoke등의 C#만의 특수한(?)것들을 사용하지 않아도 된다.
- 매우 자주 호출할 경우, 동기화(Sync)등으로 느려질 수 있는 문제가 개선될 수 도 있다.
  예) 100msec동안 수신된 데이터를 한번에 모두 처리하는 구조인 경우, 더 자연스러운 결과가 나올 수 있다.

단점 :
- 소스코드가 늘어나고,
- 실시간처리는 어렵고(보통 100msec지연)
- 메모리 사용

아래 코드는 수정해서 FIFO로 사용이 가능하다.

//구조체배열을 전역변수로 하고, 인덱스만 사용하는 방법이 좋을듯 싶다.
public class FIFO_STRUCT
{
	public enum TYPE { NULL,STR,INT,DOUBLE};
	public struct Item
	{
		public string a,b,c,Str_Value;
		public int Int_Value;
		public double Double_Value;
		public TYPE type;
	};
	Item[] item;
	int max_item_cnt;
	int r, w,cnt;
	bool bStop_wait;
	public FIFO_REPORT(int item_cnt=32)
	{
		max_item_cnt = item_cnt;
		reset();
	}
	public void reset()
	{
		item = new Item[max_item_cnt];
		r = 0;
		w = 0;
		cnt = 0;
		bStop_wait = true;
	}
	public int GetCnt()
	{
		return cnt;
	}
	bool Wait_empty()
	{
		while (cnt >= max_item_cnt)
		{
			Thread.Sleep(10);
			if (bStop_wait)
			{
				break;
			}
			else
			{ }
		}
		return cnt < max_item_cnt;
	}
	void inc_w()
	{
		w++;
		if (w >= max_item_cnt)
		{
			w = 0;
		}
		else
		{ }
		cnt++;
	}
	void inc_r()
	{
		r++;
		if (r >= max_item_cnt)
		{
			r = 0;
		}
		else
		{ }
		cnt--;
	}
	public bool Pop(out Item out_item)//데이터가 없는 경우 false리턴
	{
		bool ret = false;
		out_item = item[r];
		if (cnt>0)
		{
			inc_r();
			ret = true;
		}
		else
		{
		}
		return ret;
	}
	public void Push_wait(string a, string b, string c, string Str_Value)
	{
		if (Wait_empty())
		{
			item[w].a = a;
			item[w].b = b;
			item[w].c = c;
			item[w].Str_Value = Str_Value;
			item[w].type = TYPE.STR;
			inc_w();
		}
		else
		{ }
	}
	public void Push_wait(string a, string b, string c, int Value)
	{
		if (Wait_empty())
		{
			item[w].a = a;
			item[w].b = b;
			item[w].c = c;
			item[w].Int_Value = Value;
			item[w].type = TYPE.INT;
			inc_w();
		}
		else
		{ }
	}
	public void Push_wait(string a, string b, string c, double Value)
	{
		if (Wait_empty())
		{
			item[w].a = a;
			item[w].b = b;
			item[w].c = c;
			item[w].Double_Value = Value;
			item[w].type = TYPE.DOUBLE;
			inc_w();
		}
		else
		{ }
	}
}

'C#' 카테고리의 다른 글

ClassExcel  (0) 2020.10.10
리스트뷰 헤더 컬럼들이 안보이는 경우  (0) 2020.10.10
함수 포인터 전달  (0) 2020.10.10
Form 사이즈 변경  (0) 2020.10.10
Form 편집창이 안뜨는 문제  (0) 2020.10.10
Posted by 안녕1999
, |

함수 포인터 전달

C# / 2020. 10. 10. 23:30
public delegate void FUNC_puts(string message);//함수 포인터 타입 정의(타입=FUNC_puts)

public static void My_puts(string message)
{
    Console.WriteLine(message);
}

//아래와 같이 함수 포인터변수에 함수를 넣고, 호출할 수 있다.
FUNC_puts f = My_puts;
f("Hello World");


public static void MyFunc2(string str, int value, FUNC_puts puts)
{
    puts(str + value.ToString());
}


MyFunc2("test",1,FUNC_puts);
Posted by 안녕1999
, |

Form 사이즈 변경

C# / 2020. 10. 10. 23:27
this.AutoSizeMode = AutoSizeMode.GrowAndShrink;//사이즈 변경 마우스 커서가 나타나지 않음

From의 AutoSize속성은 Form안의 컨트롤들의 위치/크기에 따라, Form의 크기를 자동 조정하는 기능이다.
Form이 resize인 경우에도 

버튼 같은 GUI 컨트롤의 AutoSize속성은 설정된 글자크기에 맞게, 사이즈가 자동으로 변하는 기능.

Form 크기를 변경 하면, 안에 내용의 크기도 같이 변하도록 하는 방법은?


//전체화면 크기로 변경
this.Size = Screen.PrimaryScreen.WorkingArea.Size;//전체화면 크기로 변경(100%크기가 안됨)
this.WindowState = FormWindowState.Maximized;//전체화면 크기로 변경(느리고, 제대로 안그려짐)



아래와 같은 방식으로 Scale할 수 있다.

		private void Form1_SizeChanged(object sender, EventArgs e)
		{
			m_ScaleForm.Form_SizeChanged();//자식컨트롤들의 크기와 위치를 다시 계산
		}
		ScaleForm m_ScaleForm;
		private void Form1_Load(object sender, EventArgs e)
		{
			m_ScaleForm = new ScaleForm(this);//자식컨트롤들의 위치와 크기 저장

Posted by 안녕1999
, |

Form 편집창이 안뜨는 문제

C# / 2020. 10. 10. 23:27
갑자기 Form 디자인 편집창이 안뜸,
원인 : Form1.cs 에서 맨위에 class가 Form1이 아닌 다른것이 있는 경우, C#소스파일로 인식함.
Posted by 안녕1999
, |
쓰레드에서 GUI 컨트롤을 변경할 경우, 엑세스에러가 발생한다.
해결방법은 여러가지가 있으나, 여기서는
"변수와 타이머로 해결하는 방법", "FIFO를 이용한 방법"을 제시해본다.

#변수와 타이머로 해결하는 방법
===============================
쓰레드가 처리할 수 없는 GUI작업을 메인 GUI Form에서 처리하도록 부탁하는 것이다.

쓰레드에서는 호출할 동작에 대한 임시값을 변수에 설정하고,
해당 기능 호출용 변수값을 설정한다.
쓰레드에서는 호출할 동작에 대한 완료를 기다릴 필요가 있다면, 임시값이 클리어 되었는지 계속 대기한다.
예)
	MESSAGE_s="쓰레드에서 호출하는 내용";
	MESSAGE_wait=true;
	while(MESSAGE_wait==true)
    {
        Thread.Sleep(50);
    }

타이머에서는 해당기능 호출용 변수값을 확인해서,
타이머를 일시 정지할 필요가 있다면, 정지시키고,
해당 GUI 기능을 동작하고,
동작완료가 되었음을 표시하기위해, 호출용 변수값을 조작한다.
타이머 재가동이 필요하면, 재가동한다.
예)
		private void Timer100msec_Tick(object sender, EventArgs e)
		{
			if(MESSAGE_wait==true)
			{
				Timer100msec.Stop();
				GUI_MESSAGE(MESSAGE_s);
				MESSAGE_wait = false;
				Timer100msec.Start();
			}
			else
			{ }
		}
이 방법으로 메세지창등을 띄워서 작업할 수 도 있다.
변수를 몇개 더 추가해서, 결과값도 받을 수 있다.
코드 작성이 불편하긴하지만, 잘 동작한다.

문제점 : 빠르게, 연속으로, 다량의 작업을 처리하기에는 문제가 있다. 연동해야하는 GUI의 개수가 많아지면 관리가 어려워진다.



#FIFO를 이용한 방법
===============================
쓰레드에서 FIFO에 데이터를 넣고, GUI(메인)쓰레드에서 타이머에서 FIFO의 데이터를 받아서 처리한다.
마치 시리얼 통신데이터를 주고, 받는 방식이다.
쓰레드뿐만 아니라 네트워크로 확장도 가능하다.

장점 :
- 많은, 자주, 복잡한 처리도 잘 처리가 된다.
- 세밀하고, 다양한 처리가 가능하다.
- 거의 모든 환경에서 사용가능하다.

단점 :
- 정확한 시간 동기화가 필요한 경우에는 사용이 어렵다.
- 작업이 완료될때까지 기다리기 어렵다.
- 코드가 많아진다.

Posted by 안녕1999
, |
packages' 요소가 선언되지 않았습니다
=> 엑셀등의 외부라이브러리 설치가 안된 상태에서 using 작성.
예) using Excel = Microsoft.Office.Interop.Excel;
Posted by 안녕1999
, |

엑셀 패키지 관리자 설치

C# / 2020. 10. 10. 23:16
엑셀 패키지 관리자 설치
패키지 관리자에서 
Install-Package Microsoft.Office.Interop.Excel


소스폴더 이동후, 에러 발생
->패키지 관리자에서 엑셀 패키지 제거후 다시 설치
Posted by 안녕1999
, |

일관성 없는 액세스 가능성, 매개 변수 형식이 대리자보다 액세스하기 어렵습니다. class등에서 사용하는 enum, struct등이 public이 아닌것을 함수의 인자로 넣은 경우, 발생. class등에서 사용하는 enum, struct등에 public을 붙여주면 해결됨.

 

 

오류 CS0052 일관성 없는 액세스 가능성: 'xxxx' 필드 형식이 'yyyyy' 필드보다 액세스하기 어렵습니다.

 

class 작성시, public 붙여야함.

예)public class Myxxx

{

...

Posted by 안녕1999
, |

최근에 달린 댓글

글 보관함