2012-07-07 3 views
1

F # 기반 추가 기능의 Excel 명명 된 범위에서 데이터를 가져 오려고합니다. 특정 워크 시트가 아니라 통합 문서의 어디에서나 명명 된 범위를 사용할 수 있기를 원합니다.Excel ThisWorkbook.Names를 읽기 위해 변경 가능하도록 강제?

let xlRange (xl:Microsoft.Office.Interop.Excel.Application, name:string) = 
    let name_list = xl.ThisWorkbook.Names:Microsoft.Office.Interop.Excel.Names 
    let mutable result=null 
    for n in name_list do 
     let nn = n :?> Microsoft.Office.Interop.Excel.Name 
     if nn.Name = name then 
      let range=nn.RefersToRange 
      result <- range.Value2 :?> obj[,] 
    result 

위의 코드는 작동하지만이 변경 가능한 긴급한 스타일을 사용했기 때문에 나는 그것을 좋아하지 않는다. 문제는 Excel.Names 컬렉션이 제대로 작동하지 않는다는 것입니다. 예를 들어

let name_seq = Seq.toList name_list 

이 유형의 이름은 '유형과 호환되지 않습니다'서열 < '는이>'

이 있습니까

이 일을 더 F 번호 관용적 인 방법을 제공합니다 ?

+0

'Seq.toList (Seq.cast name_list)'를 시도해보십시오. 유형을 지정할 수도 있습니다 (예 :'let name_seq : ... = ...'). –

답변

1

name_list을 입력 할 때 Seq.cast을 사용해야합니다.

장점은 분명합니다. F #과의 상호 운용성이 향상되었고 명령형 for 대신 Seq module에서 상위 함수를 사용할 수있었습니다.

let xlRange (xl: Microsoft.Office.Interop.Excel.Application, name: string) = 
    xl.ThisWorkbook.Names 
    |> Seq.cast<Microsoft.Office.Interop.Excel.Name> 
    |> Seq.tryPick (fun n -> if n.Name = name 
          then Some (n.RefersToRange.Value2 :?> obj[,]) 
          else None) 

반환 유형은 이제 무료로 안전을 입력주는 obj[,] option이다.

+0

고마워요. 처음에 시도했지만''Names ''형식이 'IEnumerable'형식과 호환되지 않습니다. –

0

Seq. 호환되지 않는 유형 때문에 직접적으로 필자는 컬렉션을 F # 목록으로 변환하여 위와 같이 처리 할 수있는 기능을 만들었습니다.

let xlNamesToList names = 
    let rec xlNameList_r (names:Microsoft.Office.Interop.Excel.Names) idx = 
     if idx>names.Count then // should this be >= ? 
      [] 
     else 
      names.Item(idx)::xlNameList_r names (idx+1) 
    xlNameList_r names 0 

가 ... 그럼 내가 직접 할 수있는 간단한 방법을 발견 ... 그것은 잘 컴파일하지만 난 때문에 테스트하지 않았다 도움말들에 대한

let xlRange (xl:Microsoft.Office.Interop.Excel.Application, name:string) = 
    try 
     let r=xl.ThisWorkbook.Names.Item(name :> obj).RefersToRange 
     Some(r.Value2 :?> obj[,]) 
    with 
     | _ -> None 

감사합니다!