2017-09-25 14 views
0

私は、マクロのExcelヘッダを持つスプレッドシートを持っており、いくつかのカラムは計算カラムです。Excelシートの列ヘッダーをマッピングして、データテーブルから既存のExcelスプレッドシートにデータを挿入するにはどうすればよいですか?

私がする必要があるのは、データベースからデータを取得し、このファイルにデータを入れることです。

DataTable Excelファイルのように、クエリがすべての列をExcelファイルのように持つわけではありません。

データテーブルの列をExcelファイルにマップし、データをロードする必要があります。 このファイルを毎週作成する必要があるため、新しいデータをロードする前に、既存のデータをファイルから削除する必要があります。

私はOpenXML DocumentとEPPlusで働いたことがありません。

試み#1:使用してEPPlus

private static void OtehrMethod(DataTable dataTable, string filePath) 
{ 
    // using EPPlus 
    var package = new ExcelPackage(new FileInfo(filePath)); 

    ExcelWorksheet workSheet = package.Workbook.Worksheets["MySheet"]; 

    foreach (DataRow row in dataTable.Rows) 
    { 
     int i = 1; 
     object cellValue = workSheet.Cells[2, i].Value; 

     workSheet.Cells[1, 1].Value = Conver.ToInt(row["Id"]); 
     // break; 
     //workSheet.Cells[2, i].Value =row["First_Name"].ToString(); 
     //workSheet.Cells[3, i].Value = row["Last_Name"].ToString(); 
     //workSheet.Cells[4, i].Value = row["Job_Title"].ToString(); 
     //workSheet.Cells[5, i].Value = row["Skills"].ToString(); 
     i++; 
    } 

    package.Save(); 
} 

試み#2:

private static void SomeMethod() 
{ 
    string filePath = ConfigurationManager.AppSettings["ExcelFilePath"]; 
    string workingSheetName = ConfigurationManager.AppSettings["WorkingSheetName"]; 

    using (SpreadsheetDocument document = SpreadsheetDocument.Open(filePath, true)) 
    { 
     // WorkbookPart workbook = document.WorkbookPart; 
     WorkbookPart workbookPart = document.WorkbookPart; 
     Workbook workbook = document.WorkbookPart.Workbook; 

     int sheetIndex = 0; 

     foreach (WorksheetPart worksheetpart in workbook.WorkbookPart.WorksheetParts) 
     { 
      Worksheet worksheet = worksheetpart.Worksheet; 

      string sheetName = workbookPart.Workbook.Descendants<Sheet>().ElementAt(sheetIndex).Name; 

      if (sheetName.ToUpper() == workingSheetName.ToUpper()) 
      { 
       IEnumerable<Row> rows = worksheet.GetFirstChild<SheetData>().Descendants<Row>(); 

       foreach (Row row in rows) 
       { 
        // How do I map Excel sheet column with data table column and insert the values into Excel ? 

        // Column["FirstName"] = DTRow["FirstName"] 
        //Column["LastName"] = DTRow["LastName"] 
       } 
      } 

      sheetIndex++; 
     } 
    } 
    // throw new NotImplementedException(); 
} 

答えて

0

オープンXMLを使用してまず、EPPlusは、OpenXMLのラッパーです。したがって、以下の概念は両方に適用されます。学習曲線は、あなたが調査するために私はヴィンセント・タンプログラムで起動します急になります

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Drawing; 
using DocumentFormat.OpenXml; 
using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Spreadsheet; 
using DocumentFormat.OpenXml.Drawing.Spreadsheet; 

namespace ExcelOpenXmlSetCellValue 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string sFile = "ExcelOpenXmlSetCellValue.xlsx"; 
      if (File.Exists(sFile)) 
      { 
       File.Delete(sFile); 
      } 
      try 
      { 
       BuildWorkbook(sFile); 
       Console.WriteLine("Program end"); 
       Console.ReadLine(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(e.ToString()); 
       Console.ReadLine(); 
      } 
     } 

     private static void BuildWorkbook(string filename) 
     { 
      using (SpreadsheetDocument xl = SpreadsheetDocument.Create(filename, SpreadsheetDocumentType.Workbook)) 
      { 
       WorkbookPart wbp = xl.AddWorkbookPart(); 
       WorksheetPart wsp = wbp.AddNewPart<WorksheetPart>(); 
       Workbook wb = new Workbook(); 
       FileVersion fv = new FileVersion(); 
       fv.ApplicationName = "Microsoft Office Excel"; 
       Worksheet ws = new Worksheet(); 
       SheetData sd = new SheetData(); 

       Row r; 
       Cell c; 

       r = new Row(); 
       // For the 2nd row. I know, it's obvious, but it's recommended 
       // that you assign a value. While Excel might be able to handle 
       // a Row class without the RowIndex assigned (in a certain case), 
       // other applications might find that difficult, in particular, 
       // your own application. 
       r.RowIndex = 2; 
       c = new Cell(); 
       // "D" for 4th column. The "2" is equal to the RowIndex of the Row 
       // that the Cell class is in. Note that the number part has to be 
       // equal to the RowIndex or disaster will happen. Or worse, Excel 
       // spits out the "file corrupted" error and your user sees it. 
       c.CellReference = "D2"; 
       // by default, an unassigned DataType means CellValues.Number 
       //c.DataType = CellValues.Number; 
       c.CellValue = new CellValue("9.81"); 
       r.Append(c); 
       sd.Append(r); 

       // What if you need more Cell's in a Row? Blank lines added for readability. 
       r = new Row(); 
       r.RowIndex = 5; 

       c = new Cell(); 
       // this way, the number part is always right, but you need to 
       // assign the RowIndex first. This will make sense when you have 
       // to append many Cell classes. This is just an alternative to 
       // assigning the cell reference. 
       c.CellReference = "F" + r.RowIndex; 
       // There are 2 other string types, the SharedString and InlineString. 
       // They are discussed in another chapter. The CellValues.String type 
       // provides the most straightforward way of including text strings. 
       c.DataType = CellValues.String; 
       c.CellValue = new CellValue("Is"); 
       r.Append(c); 

       c = new Cell(); 
       c.CellReference = "G" + r.RowIndex; 
       c.DataType = CellValues.String; 
       c.CellValue = new CellValue("that in"); 
       r.Append(c); 

       c = new Cell(); 
       c.CellReference = "H" + r.RowIndex; 
       c.DataType = CellValues.String; 
       c.CellValue = new CellValue("metres per second squared?"); 
       r.Append(c); 

       // This is for row 5 
       sd.Append(r); 

       // And now, to show you sometimes the code can be rearranged a little. 
       // But because you need to append the Cell class to the Row class, 
       // it makes sense (logically and conceptually) to initialise a new Row first. 
       c = new Cell(); 
       c.CellReference = "F7"; 
       c.DataType = CellValues.String; 
       c.CellValue = new CellValue("It'd better be. Just got used to the metric system."); 
       r = new Row(); 
       r.RowIndex = 7; 
       r.Append(c); 
       sd.Append(r); 

       ws.Append(sd); 
       wsp.Worksheet = ws; 

       wsp.Worksheet.Save(); 
       Sheets sheets = new Sheets(); 
       Sheet sheet = new Sheet(); 
       sheet.Name = "Sheet1"; 
       sheet.SheetId = 1; 
       sheet.Id = wbp.GetIdOfPart(wsp); 
       sheets.Append(sheet); 
       wb.Append(fv); 
       wb.Append(sheets); 

       xl.WorkbookPart.Workbook = wb; 
       xl.WorkbookPart.Workbook.Save(); 
       xl.Close(); 
      } 
     } 
    } 
} 

そして、彼の本からの抜粋は、概念的に役立つことがあります。

をそうSheetDataクラスは、行のクラスが含まれています子供として。各Rowクラスには、子としてのCellクラスが含まれています。 Rowクラスはスプレッドシートの行 を表します。 Cellクラスは、スプレッドシート内のセルを表します。 時には明白なことがまだ言われる必要があります。

Rowクラスの というRowIndexプロパティの値を割り当てることをお勧めします。これは基本的にそのRowクラスの行番号です。 これが4行目の場合は4を割り当てます。 Open XML仕様ではRowIndexプロパティはオプションですが、スプレッドシートアプリケーションではこれを処理する方法が ではない可能性があります。 Excelでも特別な条件の下で空のRowIndexプロパティ が正しく処理されます(後で のこの章で説明します)。

セルクラスのために、あなたはこれらのプロパティのノートを取る必要がありとおり:

  • データ型 - セル値のデータ型。あなたはおそらくCellValues.NumberとCellValues.Stringを扱います。
  • CellReference - "A1形式"のセル参照。つまり、列の文字の後に行のインデックスが続くことを意味します。たとえば、「C5」は、 の第3列第5行を意味します。 「R1C1形式」(「R」列インデックス、 、「C」列インデックス、前の の例では「R5C3」となります)がありますが、これをカバーしていません。 Excelの のデフォルト値は「A1形式」です。
  • CellValue - アクションが発生する場所。 CellValueは実際にクラスであり、その主な値は文字列です。この は、数字の値も文字列形式で格納することを意味します(DataType プロパティによって、データ型が決定されます)。
  • CellFormula - セル式がある場所。しかし、別の章でそれについて読むことができます。上記の3つのプロパティは、 ハンドルの通常のものです。

もう1つ。 Rowクラスは、昇順のRowIndex順序でSheetData クラスに追加する必要があります。 Cellクラスは、昇順の列順序でRowクラスに を追加する必要があります。これは交渉可能ではありません。 それ以外の場合、Excelはエラーを嫌になります。

うまくいけば、これで十分です。もしそうでなければ、私はさらなる質問を確認します。

あなたの他の質問に答えて、計算列については、計算列のために構築するセルの右側に計算を構築してください。

+0

私は既存のXLSM SpreedSheetを削除したくありません。私はExcelシートのデータをクリアしたい、または上書きすることができます。それは複数のシートを持っています。 それは独自の報告アプリケーションであり、かなり大きいです。 私が作業しているシート上のデータは、他のシートやチャートにデータを送ります。 私はこの既存のファイルをテンプレートとして使用して、計算された列 と他の参照シートが、作業中のシートが作成されると自動的にデータを取得できるようにデータを挿入したいと思います。 – Nepsydaz

0

かなり明確です。あなたは私が個人的にコード化していない領域ですが、各シートのSheetDataはデータを消去する場所になります。以下は、既存のシートにデータを追加して変更する方法を示しヴィンセント・タンから別のプログラムには、次のとおりです。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Drawing; 
using DocumentFormat.OpenXml; 
using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Spreadsheet; 
using DocumentFormat.OpenXml.Drawing.Spreadsheet; 

namespace ExcelOpenXmlFromTemplate 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // Switch between an Excel file with the styles and stuff 
      // and an actual Excel template file. 
      // I suggest you check out the accompanying template files first 
      // to compare how the original and final files will look like. 

      //string sFileTemplate = "FinancialYearReport.xlsx"; 
      string sFileTemplate = "FinancialYearReportTemplate.xltx"; 
      string sFile = "FinancialYearReportFinal.xlsx"; 
      if (File.Exists(sFile)) 
      { 
       File.Delete(sFile); 
      } 

      if (sFileTemplate.ToLower().EndsWith(".xlsx")) 
      { 
       File.Copy(sFileTemplate, sFile); 
      } 
      else 
      { 
       // ends with .xltx 
       // Excel template files work differently. You can't work on it 
       // directly and then save the result to a different file. 
       // More details on this in the accompanying PDF. 
       byte[] ba = File.ReadAllBytes(sFileTemplate); 
       using (MemoryStream ms = new MemoryStream()) 
       { 
        ms.Write(ba, 0, ba.Length); 
        using (SpreadsheetDocument xl = SpreadsheetDocument.Open(ms, true)) 
        { 
         xl.ChangeDocumentType(SpreadsheetDocumentType.Workbook); 
         xl.Close(); 
        } 
        File.WriteAllBytes(sFile, ms.ToArray()); 
       } 
      } 

      try 
      { 
       BuildWorkbookFromTemplate(sFile); 
       Console.WriteLine("Program end"); 
       Console.ReadLine(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(e.ToString()); 
       Console.ReadLine(); 
      } 
     } 

     private static void BuildWorkbookFromTemplate(string filename) 
     { 
      string sSheetname = "FYReport"; 
      // take note that we're opening a file, and not creating a file as before 
      using (SpreadsheetDocument xl = SpreadsheetDocument.Open(filename, true)) 
      { 
       WorkbookPart wbp = xl.WorkbookPart; 

       // Get the worksheet with the required name. 
       // To be used to match the ID for the required sheet data 
       // because the Sheet class and the SheetData class aren't 
       // linked to each other directly. 
       Sheet s = null; 
       if (wbp.Workbook.Sheets.Elements<Sheet>().Count(nm => nm.Name == sSheetname) == 0) 
       { 
        // no such sheet with that name 
        xl.Close(); 
        return; 
       } 
       else 
       { 
        s = (Sheet)wbp.Workbook.Sheets.Elements<Sheet>().Where(nm => nm.Name == sSheetname).First(); 
       } 

       WorksheetPart wsp = (WorksheetPart)xl.WorkbookPart.GetPartById(s.Id.Value); 
       SheetData sd = (SheetData)wsp.Worksheet.GetFirstChild<SheetData>(); 

       // We will update in 2 ways. 
       // 1) Get the required cell, do the updates on it, then save the worksheet. 
       // 2) Create a Cell with our data, then throw it to the SheetData, then save the worksheet. 
       // If the required cell already exists, we overwrite it. If not, we create it. 

       // The difference between the 2 is that, if your worksheet doesn't have the required cell, 
       // it becomes more difficult, because you'll have to also append it to the row. 
       // More details explained in the accompanying PDF. 

       // I left the saving of the worksheet out of the UpdateCell() function 
       // because I want to be consistent with the GetCell() version of updating. 
       // So wsp.Worksheet.Save(); is done after every cell modification. 
       // Otherwise I'd put it at the end of the update function. 
       // The code is written for you to understand what's going on, not for optimisation. 

       int iPreviousYear = DateTime.Now.Year - 1; 
       int iTheYearBeforeThat = iPreviousYear - 1; 

       Cell c = null; 

       // main title 
       c = GetCell(sd, "A", 1); 
       if (c != null) 
       { 
        if (c.DataType == CellValues.SharedString) 
        { 
         c.DataType = CellValues.String; 
        } 
        c.CellValue = new CellValue(string.Format("Financial Year Report For {0}/{1}", iTheYearBeforeThat, iPreviousYear)); 
        // I was going to show you how to work with an existing value like so: 
        // c.CellValue = new CellValue(string.Format("{0} {1}/{2}", c.CellValue.Text.Trim(), iTheYearBeforeThat, iPreviousYear)); 
        // But the existing value is a string, and Excel had kindly saved it into the SharedString table 
        // when I created the template file. 
        // The shared string concept makes things a little more interesting if you really want to work with it. 
        // For now, it's what-you-see-is-what-you-get, which is much simpler. 
        wsp.Worksheet.Save(); 
       } 

       // description of the year before the last 
       c = GetCell(sd, "A", 4); 
       if (c != null) 
       { 
        if (c.DataType == CellValues.SharedString) 
        { 
         c.DataType = CellValues.String; 
        } 
        c.CellValue = new CellValue(string.Format("Year {0}", iTheYearBeforeThat)); 
        wsp.Worksheet.Save(); 
       } 

       // description of last year 
       // I'll show you the difference in code for the 2nd method of updating 
       c = new Cell(); 
       c.DataType = CellValues.String; 
       c.CellReference = "A13"; 
       c.CellValue = new CellValue(string.Format("Year {0}", iPreviousYear)); 
       UpdateCell(sd, c, 13); 
       wsp.Worksheet.Save(); 

       // We will update the revenue and operational costs of "the year before the last" FY. 
       // You would probably retrieve the values from a database and fill it here. 
       // I don't have any meaningful data anyway, so I'm gonna cheat with a randomiser... 
       // I'll use the 2nd method of updating for convenience. 
       Random rd = new Random(); 
       int i; 

       for (i = 5; i <= 8; ++i) 
       { 
        // revenue values 
        c = new Cell(); 
        c.DataType = CellValues.Number; 
        c.CellReference = "B" + i.ToString(); 
        // range from 8.0 to 12.0 
        c.CellValue = new CellValue((rd.NextDouble() * 4.0 + 8.0).ToString("f2")); 
        UpdateCell(sd, c, (uint)i); 
        wsp.Worksheet.Save(); 

        // operational cost values 
        c = new Cell(); 
        c.DataType = CellValues.Number; 
        c.CellReference = "C" + i.ToString(); 
        // range from 0.5 to 1.5 
        c.CellValue = new CellValue((rd.NextDouble() + 0.5).ToString("f2")); 
        UpdateCell(sd, c, (uint)i); 
        wsp.Worksheet.Save(); 
       } 

       // Previous financial year's revenue and operational cost values 
       for (i = 14; i <= 17; ++i) 
       { 
        // revenue values 
        c = new Cell(); 
        c.DataType = CellValues.Number; 
        c.CellReference = "B" + i.ToString(); 
        // range from 9.0 to 14.0 
        // We've got to have increased revenue, right? :) 
        c.CellValue = new CellValue((rd.NextDouble() * 5.0 + 9.0).ToString("f2")); 
        UpdateCell(sd, c, (uint)i); 
        wsp.Worksheet.Save(); 

        // operational cost values 
        c = new Cell(); 
        c.DataType = CellValues.Number; 
        c.CellReference = "C" + i.ToString(); 
        // range from 0.4 to 1.4 
        // We've got to have decreased costs, right? :) 
        c.CellValue = new CellValue((rd.NextDouble() + 0.4).ToString("f2")); 
        UpdateCell(sd, c, (uint)i); 
        wsp.Worksheet.Save(); 
       } 

       // this section is to show you that UpdateCell() works for 
       // out of order cells in the same row. Go ahead and mix up 
       // the order of the 5 cells (A25, B25, C25, D25 and E25) in 
       // the code and check that they are still ordered correctly in the file. 
       c = new Cell(); 
       c.DataType = CellValues.String; 
       c.CellReference = "B25"; 
       c.CellValue = new CellValue("2nd"); 
       UpdateCell(sd, c, 25u); 
       wsp.Worksheet.Save(); 

       c = new Cell(); 
       c.DataType = CellValues.String; 
       c.CellReference = "E25"; 
       c.CellValue = new CellValue("5th"); 
       UpdateCell(sd, c, 25u); 
       wsp.Worksheet.Save(); 

       c = new Cell(); 
       c.DataType = CellValues.String; 
       c.CellReference = "C25"; 
       c.CellValue = new CellValue("3rd"); 
       UpdateCell(sd, c, 25u); 
       wsp.Worksheet.Save(); 

       c = new Cell(); 
       c.DataType = CellValues.String; 
       c.CellReference = "A25"; 
       c.CellValue = new CellValue("1st"); 
       UpdateCell(sd, c, 25u); 
       wsp.Worksheet.Save(); 

       c = new Cell(); 
       c.DataType = CellValues.String; 
       c.CellReference = "D25"; 
       c.CellValue = new CellValue("4th"); 
       UpdateCell(sd, c, 25u); 
       wsp.Worksheet.Save(); 

       // Credits! 
       c = new Cell(); 
       c.DataType = CellValues.String; 
       c.CellReference = "A27"; 
       // well, we wouldn't want upper management to think this 
       // financial report was *easy* to generate, right? Claim credit! 
       c.CellValue = new CellValue("Generated by Vincent"); 
       UpdateCell(sd, c, 27u); 
       wsp.Worksheet.Save(); 

       c = new Cell(); 
       c.DataType = CellValues.String; 
       c.CellReference = "E27"; 
       // you could show upper management that you're working hard, 
       // and print a time that's in the wee hours of the morning... 
       // But shame on you... 
       c.CellValue = new CellValue(string.Format("Generated at {0}", DateTime.Now.ToString("dd MMM yyyy HH:mm:ss"))); 
       UpdateCell(sd, c, 27u); 
       wsp.Worksheet.Save(); 

       // we have formulae and charts to update in the template 
       xl.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true; 
       xl.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true; 

       xl.WorkbookPart.Workbook.Save(); 
       xl.Close(); 
      } 
     } 

     private static Cell GetCell(SheetData sd, string ColumnName, UInt32 RowIndex) 
     { 
      // There's a small chance that the row has no RowIndex assigned. 
      // You should know that the property RowIndex is optional. 
      // This means the following will fail. 
      // But we can't do much about a missing RowIndex in the template. 
      Row r = null; 
      Cell c = null; 
      if (sd.Elements<Row>().Count(ri => ri.RowIndex == RowIndex) > 0) 
      { 
       r = (Row)sd.Elements<Row>().Where(ri => ri.RowIndex == RowIndex).First(); 
      } 

      if (r != null) 
      { 
       string sCellReference = ColumnName.ToUpper() + RowIndex.ToString(); 
       if (r.Elements<Cell>().Count(cr => cr.CellReference.Value == sCellReference) > 0) 
       { 
        c = (Cell)r.Elements<Cell>().Where(cr => cr.CellReference.Value == sCellReference).First(); 
       } 
      } 

      return c; 
     } 

     private static void UpdateCell(SheetData sd, Cell CellData, UInt32 RowIndex) 
     { 
      // There's a small chance that the row has no RowIndex assigned. 
      // You should know that the property RowIndex is optional. 
      // This means the following will fail. 
      // But we can't do much about a missing RowIndex in the template. 
      Row r = null; 
      if (sd.Elements<Row>().Count(ri => ri.RowIndex == RowIndex) == 0) 
      { 
       // There's no row at this index, so it also means there's no cell 
       // with the data required. So just create the row with the cell. 
       r = new Row(); 
       r.RowIndex = RowIndex; 
       r.Append(CellData); 
       sd.Append(r); 
      } 
      else 
      { 
       r = (Row)sd.Elements<Row>().Where(ri => ri.RowIndex == RowIndex).First(); 
       // we will assume the cell's CellReference is consistent with the given RowIndex 
       if (r.Elements<Cell>().Count(cr => cr.CellReference.Value == CellData.CellReference.Value) > 0) 
       { 
        // there's an existing cell 
        Cell c = (Cell)r.Elements<Cell>().Where(cr => cr.CellReference.Value == CellData.CellReference.Value).First(); 
        c.DataType = CellData.DataType; 
        // reset to "normal" string value if it's a shared string. 
        // Otherwise, we'll have to go change the value in the SharedStringTable class, 
        // and that's out of scope for now. Let's focus on updating cells, shall we? 
        // We are also assuming we're not stupid enough to set the given cell's 
        // data type to be SharedString... 
        if (c.DataType == CellValues.SharedString) 
        { 
         c.DataType = CellValues.String; 
        } 
        c.CellValue = new CellValue(CellData.CellValue.Text); 

        // set any other additional properties you want 
       } 
       else 
       { 
        // no such cell 

        IEnumerable<Cell> iec = r.Elements<Cell>(); 
        // in case there are no cells in the row 
        if (iec.Count() == 0) 
        { 
         r.Append(CellData); 
        } 
        else 
        { 
         bool bFound = false; 
         // cells need to be in order of their CellReference values 
         foreach (Cell c in iec) 
         { 
          // We assume the existing Cells are already in order. 
          // This means the moment our CellData's CellReference is before 
          // a particular existing Cell's CellReference, we can insert before 
          // that particular existing Cell. 
          if (string.Compare(CellData.CellReference.Value, c.CellReference.Value) < 0) 
          { 
           bFound = true; 
           r.InsertBefore(CellData, c); 
           break; 
          } 
         } 
         // well, we have to insert our CellData *somewhere*. 
         // If not found in the loop above, then it must have the highest CellReference. 
         // So we just append it at the end of the row. 
         if (!bFound) 
         { 
          r.Append(CellData); 
         } 
        } 

        // we don't append the row to the SheetData variable because 
        // the row already exists. We just need to append the cell. 
       } 
      } 
     } 
    } 
} 
ヴィンセントの例は、テンプレートとして設定ワークブックを使用しており、セルをクリアカバーしていませんが、彼はどのように示してい

セルを上書きする。私には、彼は間違っている可能性のあるものをたくさんカバーしているように見えます。私は何もしていない細胞を上書きしようとして、それがうまくいくかどうかを見ます。

関連する問題