【NetOffice】方法 : ワークシートの範囲内のテキストを検索する

  • 2012.11.18 Sunday
  • 05:44
JUGEMテーマ:コンピュータ



Source and Project

Microsoft.Office.Interop.Excelでできる事は、NetOfficeでも似たようなコードで実現できるのではないか!?という安易な発想でMSDNに書かれているコードを試してみることにします。

今回は

方法 : ワークシートの範囲内のテキストを検索する
http://msdn.microsoft.com/ja-jp/library/e4x1k99a(v=vs.80).aspx

指定した範囲内で、何らかの条件を元に検索するのはRange.Findメソッドを利用します。さらに続けて検索する場合はRange.FindNextメソッドを利用します。
 
using System;
using System.Collections.Generic;
using System.Linq;
using NetOffice.ExcelApi;
using NetOffice.ExcelApi.Enums;

namespace Art55.NetOfficeDemo20121118_002
{
    class Program
    {
        static void Main()
        {
            var application = new Application {Visible = true};
            Worksheet worksheet = application.Workbooks.Add().Worksheets.OfType<Worksheet>().First();

            string[,] items = new []
                {
                    "green apple", "avocado", "apricot", "apple", "strawberry",
                    "fig", "orange", "persimmon", "raspberry", "kiwi", "chestnut",
                    "grapefruit", "coconut", "cherry", "watermelon", "durian", "pear",
                    "pineapple", "banana", "papaya", "loquat", "grape", "plum",
                    "blueberry", "muscat", "muskmelon", "mango", "mandarin orange",
                    "melon", "peach", "yuzu", "lime", "raspberry", "lemon"
                }
                .ToMultiArrary(5);
            Range top = worksheet.Range("A1");
            Range fruitRange = worksheet.Range(top, top.Cells[items.GetLength(0), items.GetLength(1)]);
            fruitRange.Value = items;

            FindRangeSeq(fruitRange, "apple")
                .ToList()
                .ForEach(appleRange =>
                    {
                        appleRange.Font.Color = 255.0;
                    });

        }

        private static IEnumerable<Range> FindRangeSeq(Range range, string fruitName)
        {
            string firstAddress = string.Empty;
            for (Range currentFind = range.Find(fruitName, Type.Missing,
                                     XlFindLookIn.xlValues, XlLookAt.xlPart,
                                     XlSearchOrder.xlByRows, XlSearchDirection.xlNext, false,
                                     Type.Missing, Type.Missing)
                ; currentFind != null && firstAddress != currentFind.Address
                ; currentFind = range.FindNext(currentFind))
            {
                if (string.IsNullOrEmpty(firstAddress))
                {
                    firstAddress = currentFind.Address;
                }
                yield return currentFind;
            }
        }
    }

    public static class Utils
    {
        public static IEnumerable<T[]> ToArrarySeq<T>(this IEnumerable<T> source, int count)
        {
            return source.ToGroupingSeq(
                (value, index) => index / count,
                seq => seq.ToArray());
        }

        public static IEnumerable<TGroup> ToGroupingSeq<T, TKey, TGroup>(this IEnumerable<T> source, Func<T, int, TKey> createKey, Func<IEnumerable<T>, TGroup> createInnerResult)
        {
            int rowIndex = 0;
            return source
                .GroupBy(value => createKey(value, rowIndex++))
                .Select(group => createInnerResult(group));
        }

        public static T[,] ToMultiArrary<T>(this IEnumerable<T> source, int count)
        {
            IEnumerable<T> enumerable = source as T[] ?? source.ToArray();
            return enumerable.ToMultiArrary(count, 0);
        }

        public static T[,] ToMultiArrary<T>(this IEnumerable<T> source, int count, int origin)
        {
            IEnumerable<T> seq = source as T[] ?? source.ToArray();
            var result = (T[,])Array.CreateInstance(
                typeof(T),
                new[] { seq.Count() / count + (seq.Count() % count == 0 ? 0 : 1), count },
                new[] { origin, origin });
            int index = 0;
            seq
                .ToList()
                .ForEach(value => result[index / count + origin, index++ % count + origin] = value);
            return result;
        }
    }
}

■範囲の中から特定のテキストを探す。
Range currentFind = range.Find(fruitName, Type.Missing,
XlFindLookIn.xlValues, XlLookAt.xlPart,
XlSearchOrder.xlByRows, XlSearchDirection.xlNext, false,
Type.Missing, Type.Missing)

■範囲の中から指定したカレント以降のものを探す。
currentFind = range.FindNext(currentFind)

range.FindNextは、rangeの範囲の中で値が存在し続ける限り、ループします。非常に使いづらいです。今回のサンプルコードでは、検索文字列に対して値を書き換えるような事をしていないため、終了条件は必ずみたしますが、検索するたびに値を書き換えたりしていると、現在の条件では、何周もしてしまう可能性もあります。検索の方向と前状態のアドレスを見比べるなど、やり方は色々あると思いますが、Excelの機能を使わず、.NET Frameoworkの機能でがんばるというのもありかなっと思います。





Source and Project

--------------------------------------
本投稿は、CodePlexで公開されているNetOfficeを利用しています。
NetOffice - MS Office in .NET
http://netoffice.codeplex.com/

NetOffice関連の記事は下記にまとめています。
【NetOffice】【Excel】NetOfficeのまとめ
http://pro.art55.jp/?eid=1304102
--------------------------------------

コメント
管理者の承認待ちコメントです。
  • -
  • 2018/06/06 1:24 PM
コメントする








    
この記事のトラックバックURL
トラックバック

calendar

S M T W T F S
 123456
78910111213
14151617181920
21222324252627
28293031   
<< October 2018 >>

あわせて読みたい

あわせて読みたいブログパーツ

selected entries

categories

archives

recent comment

  • 【キーボード】6年前のRealForceを復活させることはできる!?その3
    art55 (05/22)
  • 【キーボード】6年前のRealForceを復活させることはできる!?その3
    分解大好き (05/18)
  • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
    art55 (02/04)
  • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
    Gen (02/04)
  • 【キーボード】RealForce が壊れて帰ってきた。
    art55 (04/29)
  • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
    art55 (02/23)
  • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
    かるあ (02/22)
  • 【C#】Dictionaryの実装・データ構造・アルゴリズムを観察する。
    art55 (01/16)
  • 【C#】Dictionaryの実装・データ構造・アルゴリズムを観察する。
    karuakun (01/16)
  • 【NetOffice】【Excel】死なないExcelプロセスをKillする。
    art55 (12/05)

recent trackback

recommend

recommend

recommend

C#プログラマのための.NETアプリケーション最適化技法 (Programmer's SELECTION)
C#プログラマのための.NETアプリケーション最適化技法 (Programmer's SELECTION) (JUGEMレビュー »)
Sasha Goldshtein,Dima Zurbalev,Ido Flatow,サシャ・ゴルドシュタイン,ディマ・ズルバレフ,イド・フラトー

recommend

ろんりと集合
ろんりと集合 (JUGEMレビュー »)
中内 伸光
とてもわかりやすいです。

recommend

recommend

シャノン・ノイマン・ディジタル世界
シャノン・ノイマン・ディジタル世界 (JUGEMレビュー »)
市川 忠男
4章がリレーショナルデータベースな内容になってます。ページ数があまりありませんが、ポイントがものすごく的確にまとまっていて、感動します。

recommend

recommend

東プレ Realforce91UBK-S 静音キーボード 静電容量無接点方式 変荷重 ブラック NG01BS
東プレ Realforce91UBK-S 静音キーボード 静電容量無接点方式 変荷重 ブラック NG01BS (JUGEMレビュー »)

テンキーレス、静音のRealForce91UBK-S。スコスコ感がたまらなく気持ちいいです。家と会社で2台持ってます。

recommend

recommend

プログラミング.NET Framework 第4版 (プログラミングシリーズ)
プログラミング.NET Framework 第4版 (プログラミングシリーズ) (JUGEMレビュー »)
Jeffrey Richter
発売予定美 2013年10月10日。.NET Frameworkとお付き合いする人のバイブルですね。

recommend

recommend

キャット・シッターの君に。
キャット・シッターの君に。 (JUGEMレビュー »)
喜多嶋 隆
私のイラストレータデビュー本です。

recommend

Essential .NET ― 共通言語ランタイムの本質
Essential .NET ― 共通言語ランタイムの本質 (JUGEMレビュー »)
ドン・ボックス,クリス・セルズ,Don Box,Chris Sells,吉松 史彰

links

profile

search this site.

others

mobile

qrcode

powered

無料ブログ作成サービス JUGEM