Visual Studio 2010 で Excel 相互運用機能を使用して、これらすべてのデータ行をアルファベット順に並べ替えようとしています。一部はすでにアルファベット順に並んでいます。
Accountancy Graduate, Trainees Banking, Insurance, Finance
Accountancy Graduate, Trainees Customer Services
Accountancy Graduate, Trainees Education
Accountancy Graduate, Trainees Health, Nursing
Accountancy Graduate, Trainees Legal
Accountancy Graduate, Trainees Management Consultancy
Accountancy Graduate, Trainees Media, New Media, Creative
Accountancy Graduate, Trainees Oil, Gas, Alternative Energy
Accountancy Graduate, Trainees Public Sector & Services
Accountancy Graduate, Trainees Recruitment Sales
Accountancy Graduate, Trainees Secretarial, PAs, Administration
Accountancy Graduate, Trainees Telecommunications
Accountancy Graduate, Trainees Transport, Logistics
私のコードの現在のバージョンは次のとおりです (コードを fs ファイルに入れる前にインタラクティブに動作するようにしています)。
#r "office.dll"
#r "Microsoft.Office.Interop.Excel.dll"
open System;;
open System.IO;;
open Microsoft.Office.Interop.Excel;;
let app = new ApplicationClass(Visible = true)
let inputBook = app.Workbooks.Open @"C:\Users\simon.hayward\Dropbox\F# Scripts\TotalJobsSort\SortData.xlsx" //work
//let inputBook = app.Workbooks.Open @"C:\Users\Simon Hayward\Dropbox\F# Scripts\TotalJobsSort\SortData.xlsx" //home
let outputBook = app.Workbooks.Add()
let inSheet = inputBook.Worksheets.[1] :?> _Worksheet
let outSheet = outputBook.Worksheets.[1] :?> _Worksheet
let rows = inSheet.UsedRange.Rows.Count;;
let toSeq (range : Range) =
seq {
for r in 1 .. range.Rows.Count do
for c in 1 .. range.Columns.Count do
let cell = range.Item(r, c) :?> Range
yield cell
}
for i in 1 .. rows do
let mutable row = inSheet.Cells.Rows.[i] :?> Range
row |> toSeq |> Seq.map (fun x -> x.Value2.ToString()) |> Seq.sort |>
(outSheet.Cells.Rows.[i] :?> Range).Value2 <- row.Value2;;
app.Quit();;
しかし、型に問題があります。quit コマンドの前の最終行
(outSheet.Cells.Rows.[i] :?> Range).Value2 <- row.Value2;;
インテリセンスによって赤い下線が引かれ、私が得るエラーは
「この式は型 seq -> 'a を持つことが期待されていますが、ここには型 unit があります」.
VSが何を伝えようとしているのかはわかりますが、これを修正するために何度か試みましたが、型の問題を回避できないようです。
出力が出力シートに書き込まれるように、パイプラインを正しいタイプにする方法を教えてください。
編集1:これは、次のようにコメントアウトされたソート済み変数で表示される完全なエラーメッセージです
let sorted = row |> toSeq //|> Seq.map (fun x -> x.Value2.ToString()) |> Seq.sort
エラー メッセージは次のとおりです。
System.Runtime.InteropServices.COMException (0x800A03EC): HRESULT からの例外: Microsoft.Office.Interop.Excel.Range の System.RuntimeType.ForwardCallToInvokeMember (String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData) での 0x800A03EC .get_Item(Object RowIndex, Object ColumnIndex) at FSI_0122.toSeq@34-47.Invoke(Int32 c) in C:\Users\Simon Hayward\Dropbox\F# Scripts\TotalJobsSort\sortExcelScript.fsx:line 36 at Microsoft.FSharp. Collections.IEnumerator.map@109.DoMoveNext(b&) Microsoft.FSharp.Collections.IEnumerator.MapEnumerator
1.System-Collections-IEnumerator-MoveNext() at Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.takeOuter@651[T,TResult](ConcatEnumerator
2 x、ユニット unitVar0) Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.takeInner@644[T,TResult](ConcatEnumerator2 x, Unit unitVar0) at <StartupCode$FSharp-Core>.$Seq.MoveNextImpl@751.GenerateNext(IEnumerable
1&次) Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase で1.MoveNextImpl() at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase
1.System-Collections-IEnumerator-MoveNext() at Microsoft.FSharp.Collections.SeqModule.ToArray[T](IEnumerable1 source) at Microsoft.FSharp.Collections.ArrayModule.OfSeq[T](IEnumerable
1 source) at .$FSI_0122.main@() in C:\Users\Simon Hayward\Dropbox\F# Scripts\TotalJobsSort\sortExcelScript.fsx:42行目 エラーのため停止しました
編集 2: この問題は、シート全体をシーケンスに変換するように設計された toSeq 関数が原因でしょうか? 適用する場所は、1行だけに適用したいです。
toSeq の r 変数を 1 に制限しようとしましたが、これは役に立ちませんでした。
私の実際のデータがギザギザの配列であるという事実は重要ですか? 各行に常に 3 つのエントリがあるわけではなく、1 ~ 4 の間で変化します。
編集3:
トーマスの提案に基づいた、私のコードの現在の反復は次のとおりです
#r "office.dll"
#r "Microsoft.Office.Interop.Excel.dll"
open System;;
open System.IO;;
open Microsoft.Office.Interop.Excel;;
let app = new ApplicationClass(Visible = true);;
let inputBook = app.Workbooks.Open @"SortData.xlsx" //workbook
let outputBook = app.Workbooks.Add();;
let inSheet = inputBook.Worksheets.[1] :?> _Worksheet
let outSheet = outputBook.Worksheets.[1] :?> _Worksheet
let rows = inSheet.UsedRange.Rows.Count;;
let columns = inSheet.UsedRange.Columns.Count;;
// Get the row count and calculate the name of the last cell e.g. "A13"
let rangeEnd = sprintf "A%d" columns
// Get values in the range A1:A13 as 2D object array of size 13x1
let values = inSheet.Range("A1", rangeEnd).Value2 :?> obj[,]
// Read values from the first (and only) column into 1D string array
let data = [| for i in 1 .. columns -> values.[1, i] :?> string |]
// Sort the array and get a new sorted 1D array
let sorted1D = data |> Array.sort
// Turn the 1D array into 2D array (13x1), so that we can write it back
let sorted2D = Array2D.init 1 columns (fun i _ -> data.[i])
// Write the data to the output sheet in Excel
outSheet.Range("A1", rangeEnd).Value2 <- sorted2D
しかし、実際のデータには各行に可変数のエントリがあるため、標準範囲例外エラーが発生しています (これは、少なくとも過去数日間の HRESULT 例外エラーの改善です)。
したがって、個々の行ごとに列を定義するか、行の長さを for ループの変数にバインドする必要があります。(私は推測します)。