If you use FCell embedded F#/C#/VB.NET code editor then by default FCell will save the source code in the workbook as Custom XML.
You can extend the functionality and implement your own source code manager, e.g. integrate with a source code repository.
The extension uses MEF as the underlying technology. Users only need to implement a simple interface as shown below.
Implement a custom MEF component for FCell source code manager
The component is simply an assembly with exactly 1 class which implements ISourceCodeManager (defined in FCell.ManagedXll). This interface has only 2 methods:
LoadSourceCode(wbk : Workbook, lang : SourceCodeLanguage) which should return source code for given language as a string. You get a reference to ActiveWorkbook so that you can store and read some data from the workbook Custom xml, e.g. path to source code file, login to source code repository etc. This method is called when you open an embedded FCell code editor.
SaveSourceCode(wbk : Workbook, lang : SourceCodeLanguage, code : string)) is called when you save a workbook with open FCell code editor. You get a reference to the ActiveWorkbook so that you can use its Custom xml and read some data e.g. path to file where source code should be saved.
The code example below shows a simple implementation:
You can create FCell Ribbon or Custom Task Pane UI to manipulate workbook Custom XML
open System open FCell.ManagedXll open System.IO open Microsoft.Office.Interop.Excel open System.ComponentModel.Composition open System.Xml open System.Text [<Export(typeof<ISourceCodeManager>)>] type SourceCodeManager() = //this function will search workbook custom xml parts for xml with element "SourceCodeLocation" //it is assumed that if such part exists it stores the path to source code file in its inner text let getSourceLocation(wbk : Workbook) = let xmlKey = "SourceCodeLocation" let xmlParts = wbk.CustomXMLParts let count = xmlParts.Count match [|1..count|] |> Array.tryFind (fun i -> let part = xmlParts.[i] part.XML.Contains(xmlKey)) with | Some(i) -> let xmlDoc = new XmlDocument() xmlDoc.LoadXml(xmlParts.[i].XML) UTF8Encoding.UTF8.GetString(Convert.FromBase64String(xmlDoc.InnerText)) | _ -> "" interface ISourceCodeManager with member this.LoadSourceCode(wbk : Workbook, lang : SourceCodeLanguage) = //assume path to source code file is saved in workbook custom xml let sourceCodeLocation = getSourceLocation(wbk) //if file exists then read its contents and return if File.Exists(sourceCodeLocation) then File.ReadAllText(sourceCodeLocation) else "" member this.SaveSourceCode(wbk : Workbook, lang : SourceCodeLanguage, code : string) = //assume path to source code file is saved in workbook custom xml let sourceCodeLocation = getSourceLocation(wbk) //if file exists then save code from open code editor in that location if File.Exists(sourceCodeLocation) then File.WriteAllText(sourceCodeLocation, code)
Plug in SourceCodeManager extension into FCell
This extension can only be used with full FCell installation because it needs FCell embedded code editors. Simply save the extension assembly in
%FCell folder%/Extensions and restart Excel.