æã ç§ã¯éå±ãããããã¬ãè£ åããŠãããŸããŸãªããã°ã©ã ãæãå§ããŸãã ä»åã¯ãExcelã§ã®éžæã決ãŸããè¡ã®é«ããåŠçããæ¹æ³ãæ ŒçŽãããã®ãã»ã«ç¯å²ã®é«ããã©ã®ããã«èæ ®ããããªã©ãææ¡ããããšããèŠæããããŸããã Excel 2010ïŒexcel.exeã32ããããããŒãžã§ã³14.0.4756.1000ãSHA1 a805cf60a5542f21001b0ea5d142d1cd0ee00b28ïŒã解æããŸããã
çè«ããå§ããŸããã
Microsoft Officeã®VBAããã¥ã¡ã³ãã«ç®ãåãããšã2ã€ã®ããããã£ãéããŠè¡ã®é«ããååŸã§ããããšãããããŸãã
- RowHeight-æå®ãããç¯å²ã®æåã®è¡ã®é«ãããã€ã³ãåäœã§è¿ãããèšå®ããŸãã Doubleã®èªã¿åã/æžã蟌ã¿ã
- Height-ç¯å²ã®é«ãããã€ã³ãåäœã§è¡šãDoubleå€ãè¿ããŸãã èªã¿åãå°çšã
ãŸãããã¡ããã芧ãã ããïŒ Excelã®ä»æ§ãšå¶é ã è¡ã®æ倧ã®é«ãã¯409ãã€ã³ãã§ããããšãããããŸãã æ®å¿µãªãããããã¯Microsoftã®å ¬åŒããã¥ã¡ã³ããå°ãå·§åŠãªå Žåã ãã§ã¯ãããŸããã å®éãExcelã³ãŒãã§ã¯ãæ倧è¡ã®é«ãã¯2047ãã¯ã»ã«ã«èšå®ãããŠãããããã¯1535.25ãã€ã³ãã§ãã ãŸããæ倧ãã©ã³ããµã€ãºã¯409.55ãã€ã³ãã§ãã VBA / Interopã§åçŽã«å²ãåœãŠãããšã§ããã®ãããªå·šå€§ãªé«ãã®è¡ãååŸããããšã¯ã§ããŸããããè¡ãååŸããCambria Mathãã©ã³ããæåã®ã»ã«ã«èšå®ãããã©ã³ããµã€ãºã409.55ãã€ã³ãã«èšå®ã§ããŸãã ãã®åŸãExcelã¯ãã®cãªã¢ã«ãŽãªãºã ã䜿çšããŠãã»ã«åœ¢åŒã«åºã¥ããŠè¡ã®é«ããèšç®ãã2047ãã¯ã»ã«ãè¶ ããæ°ãååŸãïŒåèªãä¿¡ããïŒãè¡ãå¯èœãªæ倧ã®é«ãã«èšå®ããŸãã UIãããã®ã·ãªãŒãºã®é«ããæ±ãããšãExcelã¯é«ãã409.5ãã€ã³ãã§ãããšåãã€ããŸãããVBAãä»ããŠã·ãªãŒãºã®é«ããèŠæ±ãããšãæ£çŽãª1535.25ãã€ã³ããã€ãŸã2047ãã¯ã»ã«ã«ãªããŸãã 確ãã«ãããã¥ã¡ã³ããä¿åããåŸã§ããé«ãã¯409.5ãã€ã³ããŸã§äœäžããŸãã ãã®æäœã¯ã次ã®ãããªã§ç¢ºèªã§ããŸããhttp ïŒ //recordit.co/ivnFEsELLI
åã®æ®µèœã§ãã¯ã»ã«ãç¥ã£ãŠããŸããã Excelã¯ãå®éã«ã»ã«ã®ãµã€ãºãæŽæ°ã§æ ŒçŽããã³èšç®ããŸãïŒéåžžãå¯èœãªéããã¹ãŠãæŽæ°ã§åŠçããŸãïŒã ã»ãšãã©ã®å Žåããããã¯ãã¯ã»ã«ã«äœããã®ä¿æ°ãæãããã®ã§ãã èå³æ·±ãããšã«ãExcelã¯å€èŠ³ã®ã¹ã±ãŒã«ãéåžžã®åæ°ã®åœ¢åŒã§ä¿åããŸããããšãã°ã75ïŒ ã¹ã±ãŒã«ã¯2ã€ã®æ°å3ãš4ãšããŠä¿åãããŸãããããã圌ã¯ãã®æäœãæåŸã«ãã§ã«å®è¡ããŠããããããã¹ãŠãå°æ°ã§èæ ®ããããšããå¹æãçãŸããŸãã ããã確èªããã«ã¯ãVBAã§æ¬¡ã®ã³ãŒããèšè¿°ããŸãã
w.Rows(1).RowHeight = 75.375 Debug.Print w.Rows(1).Height
VBAã¯75ãé ããŸã 75.375ãã¯ã»ã«ã¯100.5ãã¯ã»ã«ã«ãªããExcelã¯ãããè³Œå ¥ããäœè£ããªããå°æ°éšåãæ倧100ãã¯ã»ã«ã«èœãšããŸãã VBAããã€ã³ãåäœã§è¡ã®é«ããèŠæ±ãããšãExcelã¯æ£çŽã«100ãã¯ã»ã«ããã€ã³ãã«å€æãã75ãè¿ããŸãã
ååãšããŠãã·ãªãŒãºã®é«ãã«é¢ããæ å ±ãèšè¿°ããã¯ã©ã¹ãCïŒã§èšè¿°ããããšã«ãã§ã«çæããŠããŸãã
class RowHeightInfo { public ushort Value { get; set; } // , 4. public ushort Flags { get; set; } // }
ãšããããç§ã®èšèã䜿ããªããã°ãªããŸããããExcelã§ã¯è¡ã®é«ãã¯ãã®ãŸãŸä¿åãããŸãã ã€ãŸããè¡ã®é«ãã75ãã€ã³ãããã¯ã»ã«åäœã§100ã«ãªãããã«æå®ãããŠããå Žåã400ãValueã«æ ŒçŽãããŸããFlagsã®ãã¹ãŠã®ãããã®æå³ãå®å šã«ã¯ææ¡ããŠããŸããïŒãã©ã°ã®å€ãææ¡ããã®ã¯é£ãããé·ãã§ãïŒãã®0x4000ã¯é«ããæåã§èšå®ãããŠããè¡ã«å¯ŸããŠèšå®ããã0x2000ã¯é衚瀺ã®è¡ã«å¯ŸããŠèšå®ãããŠããŸãã äžè¬ã«ãæåã§é«ããèšå®ãã衚瀺è¡ã®å ŽåãFlagsã¯ã»ãšãã©ã®å Žå0x4005ã«çãããé«ãã¯Flagsãã©ãŒãããã«åºã¥ããŠèšç®ãããè¡ã®å Žåã¯0xAãŸãã¯0x800Eã®ããããã§ãã
åã®é«ããå°ãã
ååãšããŠãexcel.exeã®ã¡ãœãããèŠãããšãã§ããŸãããã®ã¡ãœããã¯ãã€ã³ããã¯ã¹ã«ãã£ãŠè¡ã®é«ããè¿ããŸãïŒçŸããã³ãŒããæäŸããŠãããHexRaysã«æè¬ããŸãïŒã
int __userpurge GetRowHeight@<eax>(signed int rowIndex@<edx>, SheetLayoutInfo *sheetLayoutInfo@<esi>, bool flag) { RowHeightInfo *rowHeightInfo; // eax int result; // ecx if ( sheetLayoutInfo->dword1A0 ) return sheetLayoutInfo->defaultFullRowHeightMul4 | (~(sheetLayoutInfo->defaultRowDelta2 >> 14 << 15) & 0x8000); if ( rowIndex < sheetLayoutInfo->MinRowIndexNonDefault ) return sheetLayoutInfo->defaultFullRowHeightMul4 | (~(sheetLayoutInfo->defaultRowDelta2 >> 14 << 15) & 0x8000); if ( rowIndex >= sheetLayoutInfo->MaxRowIndexNonDefault ) return sheetLayoutInfo->defaultFullRowHeightMul4 | (~(sheetLayoutInfo->defaultRowDelta2 >> 14 << 15) & 0x8000); rowHeightInfo = GetRowHeightCore(sheetLayoutInfo, rowIndex); if ( !rowHeightInfo ) return sheetLayoutInfo->defaultFullRowHeightMul4 | (~(sheetLayoutInfo->defaultRowDelta2 >> 14 << 15) & 0x8000); result = 0; if ( flag || !(rowHeightInfo->Flags & 0x2000) ) result = rowHeightInfo->Value; if ( !(rowHeightInfo->Flags & 0x4000) ) result |= 0x8000u; return result; }
dword1A0ãšã¯äœãªã®ãããŸã ããããŸããã ãã®ãã©ã°ãèšå®ãããŠããå ŽæãèŠã€ãããŸããã§ãã:(
ç§ã«ãšã£ãŠãdefaultRowDelta2ãšã¯äœãªã®ããããŸã ã«è¬ã®ãŸãŸã§ãã Excelããã©ãŒãããã«åºã¥ããŠè¡ã®é«ããèšç®ããå Žåã2ã€ã®æ°å€ã®åèšãšããŠè¡šãããŸãã defaultRowDelta2ã¯ãæšæºã®è¡ã®é«ãã®ãã®åèšããã®2çªç®ã®æ°å€ã§ãã ãã©ã°ãã©ã¡ãŒã¿ãŒã®å€ãäžæè°ã§ãã falseã§æž¡ããããã©ã°ã§ãã®ã¡ãœããã®åŒã³åºããèŠãå Žæ
SheetLayoutInfoã¯ã©ã¹ããã®ã¡ãœããã«è¡šç€ºãããŸãã ã·ãŒãã®å€èŠ³ã«é¢ããããããçš®é¡ã®æ
å ±ãå€æ°ä¿åãããŠããããããã®ããã«ååãä»ããŸããã SheetLayoutInfoã«ã¯ã次ã®ãããªãã£ãŒã«ãããããŸãã
- DefaultFullRowHeightMul4-æšæºã®è¡ã®é«ãã
- MinRowIndexNonDefault-é«ããæšæºãšç°ãªãæåã®è¡ã®ã€ã³ããã¯ã¹ã
- MaxRowIndexNonDefault-é«ããæšæºãšç°ãªãæåŸã®ã·ãªãŒãºã«ç¶ãã·ãªãŒãºã®ã€ã³ããã¯ã¹ã
- DefaultRowDelta2ã¯ãæšæºã®è¡ã®é«ãã®åèšã®åãéšåã§ãã
- GroupIndexDelta-詳现ã¯åŸã»ã©
ååãšããŠããã®ã¡ãœããã®ããžãã¯ã¯ç解ã§ããŸãã
- ã·ãªãŒãºã®ã€ã³ããã¯ã¹ãéæšæºã®é«ããæã€æåã®ã€ã³ããã¯ã¹ãããå°ããå Žåãæšæºãè¿ããŸãã
- ã·ãªãŒãºã®ã€ã³ããã¯ã¹ãéæšæºã®é«ããæã€æåŸã®ã€ã³ããã¯ã¹ããã倧ããå Žåãæšæºãè¿ããŸãã
- ãã以å€ã®å Žåã¯ãGetRowHeightCoreã¡ãœããããã·ãªãŒãºã®rowHeightInfoãªããžã§ã¯ããååŸããŸãã
- rowHeightInfo == nullã®å Žåãæšæºã®è¡ã®é«ããè¿ããŸãã
- ãã©ã°ã«ã¯éæ³ããããŸãããäžè¬ã«ãrowHeightInfo.Valueã«ãããã®ãè¿ããè¡ã®é«ããæåã§èšå®ãããŠããªãå Žåãå¿çã®16çªç®ã®ããããèšå®ããŸãã
ãã®ã³ãŒããCïŒã§æžãæãããšã次ã®ããã«ãªããŸãã
const ulong HiddenRowMask = 0x2000; const ulong CustomHeightMask = 0x4000; const ushort DefaultHeightMask = 0x8000; public static ushort GetRowHeight(int rowIndex, SheetLayoutInfo sheetLayoutInfo) { ushort defaultHeight = (ushort) (sheetLayoutInfo.DefaultFullRowHeightMul4 | (~(sheetLayoutInfo.DefaultRowDelta2 >> 14 << 15) & DefaultHeightMask)); if (rowIndex < sheetLayoutInfo.MinRowIndexNonDefault) return defaultHeight; if (rowIndex >= sheetLayoutInfo.MaxRowIndexNonDefault) return defaultHeight; RowHeightInfo rowHeightInfo = GetRowHeightCore(sheetLayoutInfo, rowIndex); if (rowHeightInfo == null) return defaultHeight; ushort result = 0; if ((rowHeightInfo.Flags & HiddenRowMask) == 0) result = rowHeightInfo.Value; if ((rowHeightInfo.Flags & CustomHeightMask) == 0) result |= DefaultHeightMask; return result; }
ããã§ãGetRowHeightCoreå ã§äœãèµ·ãã£ãŠããã®ãã確èªã§ããŸãã
RowHeightInfo *__fastcall GetRowHeightCore(SheetLayoutInfo *sheetLayoutInfo, signed int rowIndex) { RowHeightInfo *result; // eax RowsGroupInfo *rowsGroupInfo; // ecx int rowInfoIndex; // edx result = 0; if ( rowIndex < sheetLayoutInfo->MinRowIndexNonDefault || rowIndex >= sheetLayoutInfo->MaxRowIndexNonDefault ) return result; rowsGroupInfo = sheetLayoutInfo->RowsGroups[sheetLayoutInfo-GroupIndexDelta + (rowIndex >> 4)]; result = 0; if ( !rowsGroupInfo ) return result; rowInfoIndex = rowsGroupInfo->Indices[rowIndex & 0xF]; if ( rowInfoIndex ) result = (rowsGroupInfo + 8 * (rowInfoIndex + rowsGroupInfo->wordBA + rowsGroupInfo->wordBC - rowsGroupInfo->wordB8)); return result; }
- ç¹°ãè¿ããŸãããæåã«ãExcelã¯è¡ã€ã³ããã¯ã¹ãå€æŽãããé«ããæã€è¡ã«ãããã©ããã確èªããããã§ãªãå Žåã¯nullãè¿ããŸãã
- ç®çã®è¡ã®ã°ã«ãŒããæ€çŽ¢ããŸã;ãã®ãããªã°ã«ãŒãããªãå Žåãnullãè¿ããŸãã
- ã°ã«ãŒãå ã®ã·ãªãŒãºã®ã€ã³ããã¯ã¹ãååŸããŸãã
- 次ã«ãã·ãªãŒãºã®ã€ã³ããã¯ã¹ã«ãã£ãŠãRowHeightInfoã¯ã©ã¹ã®ç®çã®ãªããžã§ã¯ããèŠã€ããŸãã wordBAãwordBCãwordB8-ããã€ãã®å®æ°ã ãããã¯æŽå²ãšå ±ã«ã®ã¿å€åããŸãã ååãšããŠããããã¯ã¢ã«ãŽãªãºã ã®ç解ã«åœ±é¿ããŸããã
ããã§ã¯ããããã¯ããéžââè±ããŠãRowsGroupInfoã«ã€ããŠè©³ãã説æãã䟡å€ããããŸãã Excelã¯RowHeightInfoã16åã®ã°ã«ãŒãã«ä¿åããŸããRowsGroupInfoã¯ã©ã¹ã§è¡šãããiçªç®ã®ã°ã«ãŒãã¯ãiÃ16ããiÃ16 + 15ãŸã§ã®è¡ã«é¢ããæ å ±ãä¿åããŸãã
ãã ããRowsGroupInfoã®è¡ã®é«ãæ å ±ã¯ãããçããæ¹æ³ã§ä¿åãããŸãã æãå¯èœæ§ãé«ãã®ã¯ãExcelã§å±¥æŽãä¿æããå¿ èŠãããããã§ãã
RowsGroupInfoã«ã¯3ã€ã®éèŠãªãã£ãŒã«ãããããŸããIndicesãHeightInfosãããã³RowsCountã§ãã2çªç®ã¯äžèšã®ã³ãŒãã§ã¯è¡šç€ºãããŸããïŒãã®è¡ã«ããã¯ãã§ãïŒïŒrowsGroupInfo + 8ÃïŒ...ïŒïŒãrowInfoIndexã¯ç°ãªãå€ãåãããšãã§ããããã1000ãè¶
ãããã®ãèŠãŠããŸããããIDAã§ãã®ãããªæ§é ãèšå®ããæ¹æ³ãããããŸãããRowsCountãã£ãŒã«ãã¯äžèšã®ã³ãŒãã«ã¯è¡šç€ºãããŸããããããã¯å®éã«éæšæºã®è¡ãã°ã«ãŒãã«æ ŒçŽãããæ°ã§ãã
ããã«ãSheetLayoutInfoã«ã¯GroupIndexDeltaããããŸããããã¯ãã°ã«ãŒãã®å®éã®ã€ã³ããã¯ã¹ãšãè¡ã®é«ããå€æŽãããæåã®ã°ã«ãŒãã®ã€ã³ããã¯ã¹ãšã®å·®ã§ãã
Indicesãã£ãŒã«ãã«ã¯ãã°ã«ãŒãå ã®ã·ãªãŒãºã®åã€ã³ããã¯ã¹ã®RowHeightInfoãªãã»ãããæ ŒçŽãããŸãã ãããã¯é çªã«æ ŒçŽãããŸãããHeightInfosã§ã¯RowHeightInfoã¯ãã§ã«å€æŽã®é åºã§æ ŒçŽãããŠããŸãã
æ°ãã空çœã®ã·ãŒãããããè¡çªå·23ã®é«ããäœããã®æ¹æ³ã§å€æŽãããšä»®å®ããŸãããã®è¡ã¯16è¡ã®2çªç®ã®ã°ã«ãŒãã«ããã次ã®ããã«ãªããŸãã
- Excelã¯ããã®ã·ãªãŒãºã®ã°ã«ãŒãã€ã³ããã¯ã¹ã決å®ããŸãã çŸåšã®å Žåãã€ã³ããã¯ã¹ã¯1ã«ãªããGroupIndexDelta = -1ã«å€æŽãããŸãã
- äžé£ã®è¡ã®RowsGroupInfoã¯ã©ã¹ã®ãªããžã§ã¯ããäœæãããããsheetLayoutInfo-> RowsGroupsã®ã€ã³ããã¯ã¹0ïŒsheetLayoutInfo-> GroupIndexDelta + 1ïŒã®äžã«é 眮ããŸãã
- RowsGroupInfoã§ã¯ãExcelã¯RowsCountãwordBAãwordBCãwordB8ãªã©ã®16åã®4ãã€ãã€ã³ããã¯ã¹ã«ã¡ã¢ãªãå²ãåœãŠãŸãã
- 次ã«ãExcelã¯ãããåäœã®ANDæŒç®ã䜿çšããŠãã°ã«ãŒãå ã®ã·ãªãŒãºã®ã€ã³ããã¯ã¹ãèšç®ããŸãïŒããã¯ãé€ç®ã®æ®ããååŸãããããã¯ããã«é«éã§ãïŒïŒrowIndexïŒ0xFã ã°ã«ãŒãå ã®ç®çã®ã€ã³ããã¯ã¹ã¯æ¬¡ã®ããã«ãªããŸãã23ïŒ0xF = 7;
- ãã®åŸãExcelã¯ã€ã³ããã¯ã¹7ã®ãªãã»ãããååŸããŸãïŒoffset = Indices [7]ã offset = 0ã®å ŽåãExcelã¯RowsGroupIntoã®æåŸã«8ãã€ããå²ãåœãŠãRowsCountã1å¢ãããæ°ãããªãã»ãããã€ã³ããã¯ã¹[7]ã«æžã蟌ã¿ãŸãã ãããã®å Žåã§ããæåŸã«ãExcelã¯æ°ããè¡ã®é«ããšãã©ã°ã«é¢ããæ å ±ãRowsGroupInfoã«ãªãã»ããã§æžã蟌ã¿ãŸãã
Cows RowsGroupInfoã¯ã©ã¹èªäœã¯æ¬¡ã®ããã«ãªããŸãã
class RowsGroupInfo { public int[] Indices { get; } public List<RowHeightInfo> HeightInfos { get; } public RowsGroupInfo() { Indices = new int[SheetLayoutInfo.MaxRowsCountInGroup]; HeightInfos = new List<RowHeightInfo>(); for (int i = 0; i < SheetLayoutInfo.MaxRowsCountInGroup; i++) { Indices[i] = -1; } } }
GetRowHeightCoreã¡ãœããã¯æ¬¡ã®ããã«ãªããŸãã
static RowHeightInfo GetRowHeightCore(SheetLayoutInfo sheetLayoutInfo, int rowIndex) { if (rowIndex < sheetLayoutInfo.MinRowIndexNonDefault || rowIndex >= sheetLayoutInfo.MaxRowIndexNonDefault) return null; RowsGroupInfo rowsGroupInfo = sheetLayoutInfo.RowsGroups[sheetLayoutInfo.GroupIndexDelta + (rowIndex >> 4)]; if (rowsGroupInfo == null) return null; int rowInfoIndex = rowsGroupInfo.Indices[rowIndex & 0xF]; return rowInfoIndex != -1 ? rowsGroupInfo.HeightInfos[rowInfoIndex] : null; }
ãããSetRowHeightã®å€èŠ³ã§ãïŒexcel.exeããã³ãŒãããªã¹ãããŸããã§ããïŒã
public static void SetRowHeight(int rowIndex, ushort newRowHeight, ushort flags, SheetLayoutInfo sheetLayoutInfo) { sheetLayoutInfo.MaxRowIndexNonDefault = Math.Max(sheetLayoutInfo.MaxRowIndexNonDefault, rowIndex + 1); sheetLayoutInfo.MinRowIndexNonDefault = Math.Min(sheetLayoutInfo.MinRowIndexNonDefault, rowIndex); int realGroupIndex = rowIndex >> 4; if (sheetLayoutInfo.RowsGroups.Count == 0) { sheetLayoutInfo.RowsGroups.Add(null); sheetLayoutInfo.GroupIndexDelta = -realGroupIndex; } else if (sheetLayoutInfo.GroupIndexDelta + realGroupIndex < 0) { int bucketSize = -(sheetLayoutInfo.GroupIndexDelta + realGroupIndex); sheetLayoutInfo.RowsGroups.InsertRange(0, new RowsGroupInfo[bucketSize]); sheetLayoutInfo.GroupIndexDelta = -realGroupIndex; } else if (sheetLayoutInfo.GroupIndexDelta + realGroupIndex >= sheetLayoutInfo.RowsGroups.Count) { int bucketSize = sheetLayoutInfo.GroupIndexDelta + realGroupIndex - sheetLayoutInfo.RowsGroups.Count + 1; sheetLayoutInfo.RowsGroups.AddRange(new RowsGroupInfo[bucketSize]); } RowsGroupInfo rowsGroupInfo = sheetLayoutInfo.RowsGroups[sheetLayoutInfo.GroupIndexDelta + realGroupIndex]; if (rowsGroupInfo == null) { rowsGroupInfo = new RowsGroupInfo(); sheetLayoutInfo.RowsGroups[sheetLayoutInfo.GroupIndexDelta + realGroupIndex] = rowsGroupInfo; } int rowInfoIndex = rowsGroupInfo.Indices[rowIndex & 0xF]; RowHeightInfo rowHeightInfo; if (rowInfoIndex == -1) { rowHeightInfo = new RowHeightInfo(); rowsGroupInfo.HeightInfos.Add(rowHeightInfo); rowsGroupInfo.Indices[rowIndex & 0xF] = rowsGroupInfo.HeightInfos.Count - 1; } else { rowHeightInfo = rowsGroupInfo.HeightInfos[rowInfoIndex]; } rowHeightInfo.Value = newRowHeight; rowHeightInfo.Flags = flags; }
ã¡ãã£ãšããç·Žç¿
äžèšã®äŸã®åŸãè¡23ã®é«ããå€æŽãããšãExcelã¯æ¬¡ã®ããã«ãªããŸãïŒè¡23ã®é«ãã75ãã€ã³ãã«èšå®ããŸãïŒã
- DefaultFullRowHeightMul4 = 80
- DefaultRowDelta2 = 5
- MaxRowIndexNonDefault = 24
- MinRowIndexNonDefault = 23
- GroupIndexDelta = -1
- RowsGroups Count = 1
- [0] RowsGroupInfo
- HeightInfosã«ãŠã³ã= 1
- [0] RowHeightInfo
- ãã©ã°= 0x4005
- å€= 100
- ææ°
- [0] = -1
- [1] = -1
- [2] = -1
- [3] = -1
- [4] = -1
- [5] = -1
- [6] = -1
- [7] = 0
- [8] = -1
- [9] = -1
- [10] = -1
- [11] = -1
- [12] = -1
- [13] = -1
- [14] = -1
- [15] = -1
ãããšæ¬¡ã®äŸã§ã¯ãã¡ã¢ãªããã®çŽæ¥ãã³ãã¯ããŸãæçã§ã¯ãªããããVisual Studioã§èªå·±èšè¿°ã¯ã©ã¹ããäœæãããExcelã¡ã¢ãªå ã®ããŒã¿ã®å€èŠ³ã®æŠç¥å³ãã¬ã€ã¢ãŠãããŸãã
23è¡ç®ãé衚瀺ã«ããŸãããããããè¡ãã«ã¯ããã©ã°ã®0x2000ããããèšå®ããŸãã ã¡ã¢ãªãã©ã€ãã«å€æŽããŸãã çµæã¯ãã®ãããªã§èŠãããšãã§ããŸãïŒ http : //recordit.co/79vYIbwbzB
è¡ãé衚瀺ã«ãããã³ã«ãExcelã¯åãããšãè¡ããŸãã
次ã«ãè¡ã®é«ããæ瀺çã«ã§ã¯ãªããã»ã«åœ¢åŒã§èšå®ããŸãããã ã»ã«A20ã®ãã©ã³ãã®é«ãã40ãã€ã³ãã«ãããšãã»ã«ã®é«ãã¯ãã€ã³ãã§45.75ã«ãªããExcelã¡ã¢ãªã§ã¯æ¬¡ã®ããã«ãªããŸãã
- DefaultFullRowHeightMul4 = 80
- DefaultRowDelta2 = 5
- MaxRowIndexNonDefault = 24
- MinRowIndexNonDefault = 20
- GroupIndexDelta = -1
- RowsGroups Count = 1
- [0] RowsGroupInfo
- HeightInfosã«ãŠã³ã= 2
- [0] RowHeightInfo
- ãã©ã°= 0x4005
- å€= 100
- [1] RowHeightInfo
- ãã©ã°= 0x800E
- å€= 244
- ææ°
- [0] = -1
- [1] = -1
- [2] = -1
- [3] = -1
- [4] = 1
- [5] = -1
- [6] = -1
- [7] = 0
- [8] = -1
- [9] = -1
- [10] = -1
- [11] = -1
- [12] = -1
- [13] = -1
- [14] = -1
- [15] = -1
è¡ã®é«ããæšæºã§ã¯ãªãå ŽåãExcelã¯åžžã«è¡ã®é«ããä¿åããããšã«æ°ä»ããããããŸããã é«ããæ瀺çã«èšå®ãããŠããªããŠããã»ã«ãŸãã¯æžåŒã®å 容ã«åºã¥ããŠèšç®ãããŠããå Žåã§ããExcelã¯ãããäžåºŠèšç®ããçµæãé©åãªã°ã«ãŒãã«å ¥ããŸãã
è¡ã®æ¿å ¥/åé€ãåŠçããŸã
è¡ã®æ¿å ¥/åé€æã«äœãèµ·ãããã解æããããšã¯èå³æ·±ãã§ãããã excel.exeã®å¯Ÿå¿ããã³ãŒããèŠã€ããã®ã¯é£ãããããŸããããéã¢ã»ã³ãã«ããå¿ èŠã¯ãããŸããã§ããããã®äžéšãã芧ãã ããã
ãã©ã°a5ã¯ãçŸåšè¡ãããŠããæäœã決å®ããŸãã
int __userpurge sub_305EC930@<eax>(int a1@<eax>, int a2@<edx>, int a3@<ecx>, int a4, int a5, int a6) { int v6; // esi int v7; // ebx int v8; // edi int v9; // edx int v10; // ecx size_t v11; // eax _WORD *v12; // ebp size_t v13; // eax size_t v14; // eax int v15; // eax unsigned __int16 *v16; // ecx _WORD *v17; // eax _WORD *v18; // ecx int v19; // edx __int16 v20; // bx int v21; // eax _WORD *v22; // ecx int v24; // edx int v25; // eax int v26; // esi int v27; // ebx size_t v28; // eax int v29; // ebp size_t v30; // eax int v31; // esi size_t v32; // eax int v33; // eax unsigned __int16 *v34; // ecx int v35; // eax _WORD *v36; // edx _WORD *v37; // ecx int v38; // eax __int16 v39; // bx int v40; // eax _WORD *v41; // ecx int v42; // [esp+10h] [ebp-48h] int v43; // [esp+10h] [ebp-48h] int v44; // [esp+14h] [ebp-44h] char v45; // [esp+14h] [ebp-44h] int Dst[16]; // [esp+18h] [ebp-40h] int v47; // [esp+5Ch] [ebp+4h] int v48; // [esp+60h] [ebp+8h] v6 = a1; v7 = a1 & 0xF; v8 = a2; if ( !a5 ) { v24 = a4 - a1; v25 = a1 - a3; v43 = a4 - v6; if ( v7 >= v25 ) v7 = v25; v47 = a4 - v7; v26 = v6 - v7; v27 = v7 + 1; v48 = v27; if ( !v8 ) return v27; v28 = 4 * v24; if ( (4 * v24) > 0x40 ) v28 = 64; v45 = v27 + v26; v29 = (v27 + v26) & 0xF; memmove(Dst, (v8 + 4 * v29), v28); v30 = 4 * v27; if ( (4 * v27) > 0x40 ) v30 = 64; v31 = v26 & 0xF; memmove((v8 + 4 * (v47 & 0xF)), (v8 + 4 * v31), v30); v32 = 4 * v43; if ( (4 * v43) > 0x40 ) v32 = 64; memmove((v8 + 4 * v31), Dst, v32); if ( !a6 ) return v48; v33 = v29; if ( v29 < v29 + v43 ) { v34 = (v8 + 4 * v29 + 214); do { Dst[v33++] = *v34 >> 15; v34 += 2; } while ( v33 < v29 + v43 ); } v35 = (v45 - 1) & 0xF; if ( v35 >= v31 ) { v36 = (v8 + 4 * ((v27 + v47 - 1) & 0xF) + 214); v37 = (v8 + 4 * ((v45 - 1) & 0xF) + 214); v38 = v35 - v31 + 1; do { v39 = *v37 ^ (*v37 ^ *v36) & 0x7FFF; v37 -= 2; *v36 = v39; v36 -= 2; --v38; } while ( v38 ); v27 = v48; } v40 = v31; if ( v31 >= v31 + v43 ) return v27; v41 = (v8 + 4 * v31 + 214); do { *v41 = *v41 & 0x7FFF | (LOWORD(Dst[v40++]) << 15); v41 += 2; } while ( v40 < v31 + v43 ); return v27; } v9 = a1 - a4; v10 = a3 - a1; v42 = a1 - a4; v48 = 16 - v7; if ( 16 - v7 >= v10 ) v48 = v10; if ( !v8 ) return v48; v11 = 4 * v9; if ( (4 * v9) > 0x40 ) v11 = 64; v12 = (v8 + 4 * (a4 & 0xF)); v44 = a4 & 0xF; memmove(Dst, v12, v11); v13 = 4 * v48; if ( (4 * v48) > 0x40 ) v13 = 64; memmove(v12, (v8 + 4 * v7), v13); v14 = 4 * v42; if ( (4 * v42) > 0x40 ) v14 = 64; memmove((v8 + 4 * ((a4 + v48) & 0xF)), Dst, v14); if ( !a6 ) return v48; v15 = a4 & 0xF; if ( v44 < v44 + v42 ) { v16 = (v8 + 4 * v44 + 214); do { Dst[v15++] = *v16 >> 15; v16 += 2; } while ( v15 < v44 + v42 ); } if ( v7 < v48 + v7 ) { v17 = (v8 + 4 * v7 + 214); v18 = v12 + 107; v19 = v48; do { v20 = *v17 ^ (*v17 ^ *v18) & 0x7FFF; v17 += 2; *v18 = v20; v18 += 2; --v19; } while ( v19 ); } v21 = a4 & 0xF; if ( v44 >= v44 + v42 ) return v48; v22 = (v8 + 4 * (v44 + v48) + 214); do { *v22 = *v22 & 0x7FFF | (LOWORD(Dst[v21++]) << 15); v22 += 2; } while ( v21 < v44 + v42 ); return v48; }
ããã«ãå€èŠ³ã§ã¯ãããã§äœãèµ·ãã£ãŠãããã倧ãŸãã«ç解ããæ®ããéæ¥çãªå
åã§çµäºããããšãã§ããŸãã
ãããã®éæ¥çãªæ©èœãç¹å®ããããšããŸãã ãŸããè¡16ã64ã®é«ããã©ã³ãã ãªé åºã§èšå®ããŸãã 次ã«ãã€ã³ããã¯ã¹39ã®äžã®è¡ã®åã«ãæ°ããè¡ãæ¿å
¥ããŸãã æ°ããè¡ã¯è¡38ã®é«ããã³ããŒããŸãã
ã·ãªãŒãºãè¿œå ããååŸã®ã·ãªãŒãºã°ã«ãŒãã®æ
å ±ãèŠãŠã¿ãŸãããã倧èãªéãã匷調ããŸããã
è¡ãè¿œå ããåã« | è¡ãè¿œå ããåŸ |
---|---|
æåã®ã°ã«ãŒãã®å€äœïŒ | æåã®ã°ã«ãŒãã®å€äœïŒ |
0Eã04ã07ã00ã05ã0Aã09ã0Fã03ã06ã08ã0Dã01ã0Bã0Cã02 | 0Eã04ã07ã00ã05ã0Aã09ã0Fã03ã06ã08ã0Dã01ã0Bã0Cã02 |
æåã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ | æåã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ |
05ã2Bã35ã45ã4Bã50ã5Bã6Bã7Bã8BãA5ãABãB0ãB5ãE0ã100 | 05ã2Bã35ã45ã4Bã50ã5Bã6Bã7Bã8BãA5ãABãB0ãB5ãE0ã100 |
2çªç®ã®ã°ã«ãŒãã®å€äœïŒ | 2çªç®ã®ã°ã«ãŒãã®å€äœïŒ |
06ã02ã0Eã09ã01ã07ã0Fã0C ã00ã0Aã04ã0Bã 03ã08ã0Dã05 | 06ã02ã0Eã09ã01ã07ã0Fã05ã0Cã00ã0Aã04ã0Bã 03ã08ã0D |
2çªç®ã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ | 2çªç®ã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ |
10ã15ã20ã25ã30ã75ã85ã90ã9BãA0ãC5ãCBãD0ãD5ãE5ãF0 | 10ã15ã20ã25ã30 ãF0ã85ã90ã9BãA0ãC5ãCBãD0ãD5ãE5ãF0 |
3çªç®ã®ã°ã«ãŒãã®å€äœïŒ | 3çªç®ã®ã°ã«ãŒãã®å€äœïŒ |
0Cã08ã0Eã07ã0Aã01ã06ã0Fã09ã0Dã00ã05ã0Bã02ã04ã03 | 03ã0Cã08ã0Eã07ã0Aã01ã06ã0Fã09ã0Dã00ã05ã0Bã02ã04 |
3çªç®ã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ | 3çªç®ã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ |
0Bã1Bã3Bã40ã55ã60ã65ã70ã80ã95ãBBãC0ãDBãEBãF5ãFB | 0Bã1Bã3Bã75ã55ã60ã65ã70ã80ã95ãBBãC0ãDBãEBãF5ãFB |
4çªç®ã®ã°ã«ãŒãã®ãªãã»ããïŒ | 4çªç®ã®ã°ã«ãŒãã®ãªãã»ããïŒ |
_ | 00 |
4çªç®ã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ | 4çªç®ã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ |
_ | 40 |
ããã¯äºæ³ããããã®ã§ããExcelã¯2çªç®ã®ã°ã«ãŒãã«ã€ã³ããã¯ã¹7ïŒ39ïŒ0xFïŒã®æ°ããè¡ãæ¿å ¥ããŸãããªãã»ããã¯0x05ã§ãã€ã³ããã¯ã¹6ã®è¡ã®é«ããã³ããŒããŸããã°ã«ãŒããæåŸã®è¡ã¯ãããã4çªç®ã«ããã·ã¥ãããŸãã
29è¡ç®ãåé€ãããšã©ããªããèŠãŠã¿ãŸãããã
è¡ãåé€ããåã« | è¡ãåé€ããåŸ |
---|---|
æåã®ã°ã«ãŒãã®å€äœïŒ | æåã®ã°ã«ãŒãã®å€äœïŒ |
0Eã 04ã07ã00ã05ã0Aã09ã0Fã03ã06ã08ã0Dã01ã0Bã0Cã02 | 0Eã 04ã07ã00ã05ã0Aã09ã0Fã03ã06ã08ã0Dã01ã0Cã02ã0B |
æåã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ | æåã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ |
05ã2Bã35ã45ã4Bã50ã5Bã6Bã7Bã8BãA5ã AB ãB0ãB5ãE0ã100 | 05ã2Bã35ã45ã4Bã50ã5Bã6Bã7Bã8BãA5ã85ãB0ãB5ãE0ã100 |
2çªç®ã®ã°ã«ãŒãã®å€äœïŒ | 2çªç®ã®ã°ã«ãŒãã®å€äœïŒ |
06ã02ã0Eã09ã01ã07ã0Fã05ã0Cã00ã0Aã04ã0Bã03ã08ã0D | 02ã0Eã09ã01ã07ã0Fã05ã0Cã00ã0Aã04ã0Bã03ã08ã0Dã 06 |
2çªç®ã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ | 2çªç®ã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ |
10ã15ã20ã25ã30ãF0ã85ã90ã9BãA0ãC5ãCBãD0ãD5ãE5ãF0 | 10ã15ã20ã25ã30ãF0ã75ã90ã9BãA0ãC5ãCBãD0ãD5ãE5ãF0 |
3çªç®ã®ã°ã«ãŒãã®å€äœïŒ | 3çªç®ã®ã°ã«ãŒãã®å€äœïŒ |
03ã0Cã08ã0Eã07ã0Aã01ã06ã0Fã09ã0Dã00ã05ã0Bã02ã04 | 0Cã08ã0Eã07ã0Aã01ã06ã0Fã09ã0Dã00ã05ã0Bã02ã04ã03 |
3çªç®ã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ | 3çªç®ã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ |
0Bã1Bã3Bã75ã55ã60ã65ã70ã80ã95ãBBãC0ãDBãEBãF5ãFB | 0Bã1Bã3Bã40ã55ã60ã65ã70ã80ã95ãBBãC0ãDBãEBãF5ãFB |
4çªç®ã®ã°ã«ãŒãã®ãªãã»ããïŒ | 4çªç®ã®ã°ã«ãŒãã®ãªãã»ããïŒ |
00 | 00 |
4çªç®ã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ | 4çªç®ã®ã°ã«ãŒãã®è¡ã®é«ãã®å€ïŒ |
40 | 50 |
ååãšããŠãè¡ãåé€ããããšãæ¿å ¥ãšå察ã®æäœãçºçããŸãã åæã«ã4çªç®ã®ã°ã«ãŒãã¯ååšãç¶ããããã«ããè¡ã®é«ãã®å€ã¯ã察å¿ãããã©ã°-0x8005ãæã€æšæºã®é«ãã§åããããŸãã
ãã®ããŒã¿ã¯ãCïŒã§ãã®ã¢ã«ãŽãªãºã ãåçŸããã®ã«ååã§ãã
public static void InsertRow(SheetLayoutInfo sheetLayoutInfo, int rowIndex) { if (rowIndex >= sheetLayoutInfo.MaxRowIndexNonDefault) return; RowHeightInfo etalonRowHeightInfo = GetRowHeightCore(sheetLayoutInfo, rowIndex); RowHeightInfo newRowHeightInfo = etalonRowHeightInfo != null ? etalonRowHeightInfo.Clone() : CreateDefaultRowHeight(sheetLayoutInfo); int realGroupIndex = (rowIndex + 1) >> 4; int newRowInGroupIndex = (rowIndex + 1) & 0xF; int groupIndex; for (groupIndex = realGroupIndex + sheetLayoutInfo.GroupIndexDelta; groupIndex < sheetLayoutInfo.RowsGroups.Count; groupIndex++, newRowInGroupIndex = 0) { if (groupIndex < 0) continue; if (groupIndex == SheetLayoutInfo.MaxGroupsCount) break; RowsGroupInfo rowsGroupInfo = sheetLayoutInfo.RowsGroups[groupIndex]; if (rowsGroupInfo == null) { if ((newRowHeightInfo.Flags & CustomHeightMask) == 0) continue; rowsGroupInfo = new RowsGroupInfo(); sheetLayoutInfo.RowsGroups[groupIndex] = rowsGroupInfo; } int rowInfoIndex = rowsGroupInfo.Indices[newRowInGroupIndex]; RowHeightInfo lastRowHeightInGroup; if (rowInfoIndex == -1 || rowsGroupInfo.HeightInfos.Count < SheetLayoutInfo.MaxRowsCountInGroup) { lastRowHeightInGroup = GetRowHeightCore(sheetLayoutInfo, ((groupIndex - sheetLayoutInfo.GroupIndexDelta) << 4) + SheetLayoutInfo.MaxRowsCountInGroup - 1); Array.Copy(rowsGroupInfo.Indices, newRowInGroupIndex, rowsGroupInfo.Indices, newRowInGroupIndex + 1, SheetLayoutInfo.MaxRowsCountInGroup - 1 - newRowInGroupIndex); rowsGroupInfo.HeightInfos.Add(newRowHeightInfo); rowsGroupInfo.Indices[newRowInGroupIndex] = rowsGroupInfo.HeightInfos.Count - 1; } else { int lastIndex = rowsGroupInfo.Indices[SheetLayoutInfo.MaxRowsCountInGroup - 1]; lastRowHeightInGroup = rowsGroupInfo.HeightInfos[lastIndex]; Array.Copy(rowsGroupInfo.Indices, newRowInGroupIndex, rowsGroupInfo.Indices, newRowInGroupIndex + 1, SheetLayoutInfo.MaxRowsCountInGroup - 1 - newRowInGroupIndex); rowsGroupInfo.HeightInfos[lastIndex] = newRowHeightInfo; rowsGroupInfo.Indices[newRowInGroupIndex] = lastIndex; } newRowHeightInfo = lastRowHeightInGroup ?? CreateDefaultRowHeight(sheetLayoutInfo); } if ((newRowHeightInfo.Flags & CustomHeightMask) != 0 && groupIndex != SheetLayoutInfo.MaxGroupsCount) { SetRowHeight(((groupIndex - sheetLayoutInfo.GroupIndexDelta) << 4) + newRowInGroupIndex, newRowHeightInfo.Value, newRowHeightInfo.Flags, sheetLayoutInfo); } else { sheetLayoutInfo.MaxRowIndexNonDefault = Math.Min(sheetLayoutInfo.MaxRowIndexNonDefault + 1, SheetLayoutInfo.MaxRowsCount); } }
public static void RemoveRow(SheetLayoutInfo sheetLayoutInfo, int rowIndex) { if (rowIndex >= sheetLayoutInfo.MaxRowIndexNonDefault) return; int realGroupIndex = rowIndex >> 4; int newRowInGroupIndex = rowIndex & 0xF; int groupIndex; for (groupIndex = realGroupIndex + sheetLayoutInfo.GroupIndexDelta; groupIndex < sheetLayoutInfo.RowsGroups.Count; groupIndex++, newRowInGroupIndex = 0) { if (groupIndex < -1) continue; if (groupIndex == -1) { sheetLayoutInfo.RowsGroups.Insert(0, null); sheetLayoutInfo.GroupIndexDelta++; groupIndex = 0; } if (groupIndex == SheetLayoutInfo.MaxGroupsCount) break; var newRowHeightInfo = groupIndex == SheetLayoutInfo.MaxGroupsCount - 1 ? null : GetRowHeightCore(sheetLayoutInfo, (groupIndex - sheetLayoutInfo.GroupIndexDelta + 1) << 4); RowsGroupInfo rowsGroupInfo = sheetLayoutInfo.RowsGroups[groupIndex]; if (rowsGroupInfo == null) { if (newRowHeightInfo == null || (newRowHeightInfo.Flags & CustomHeightMask) == 0) continue; rowsGroupInfo = new RowsGroupInfo(); sheetLayoutInfo.RowsGroups[groupIndex] = rowsGroupInfo; } if (newRowHeightInfo == null) { newRowHeightInfo = CreateDefaultRowHeight(sheetLayoutInfo); } int rowInfoIndex = rowsGroupInfo.Indices[newRowInGroupIndex]; if (rowInfoIndex == -1) { for (int i = newRowInGroupIndex; i < SheetLayoutInfo.MaxRowsCountInGroup - 1; i++) { rowsGroupInfo.Indices[i] = rowsGroupInfo.Indices[i + 1]; } rowsGroupInfo.HeightInfos.Add(newRowHeightInfo); rowsGroupInfo.Indices[SheetLayoutInfo.MaxRowsCountInGroup - 1] = rowsGroupInfo.HeightInfos.Count - 1; } else { for(int i = newRowInGroupIndex; i < rowsGroupInfo.HeightInfos.Count - 1; i++) { rowsGroupInfo.Indices[i] = rowsGroupInfo.Indices[i + 1]; } rowsGroupInfo.Indices[rowsGroupInfo.HeightInfos.Count - 1] = rowInfoIndex; rowsGroupInfo.HeightInfos[rowInfoIndex] = newRowHeightInfo; } } if(rowIndex <= sheetLayoutInfo.MinRowIndexNonDefault) { sheetLayoutInfo.MinRowIndexNonDefault = Math.Max(sheetLayoutInfo.MinRowIndexNonDefault - 1, 0); } }
äžèšã®ã³ãŒãã¯ãã¹ãŠGitHubã§èŠã€ããããšãã§ããŸã
çµè«
Excelã³ãŒããèå³æ·±ãããªãã¯ã«é©ããã®ã¯ãããåããŠã§ã¯ãããŸããã ä»åã¯ãè¡ã®é«ãã«é¢ããæ å ±ã圌ãã©ã®ããã«ä¿åããããç¥ããŸããã ã³ãã¥ããã£ã«èå³ãããå Žåã¯ã次ã®èšäºã§Excelãã»ã«ç¯å²ã®é«ããã©ã®ããã«èæ ®ãããã瀺ããŸãïŒãã¿ãã¬ïŒSQRTå解ã«äŒŒããã®ããããŸãããäœããã®çç±ã§åèšããã£ãã·ã¥ããã«ïŒãæŽæ°ã§ã¹ã±ãŒãªã³ã°ãé©çšããæ¹æ³ãèŠãããšãã§ããŸãã