citavi合并重复文献题录

本文介绍了如何在Citavi中使用宏代码自动检测并合并重复的引用记录,包括规则、步骤和注意事项。

一、宏macro的使用方法

参考官方文档 Using macros - Citavi 6 Manual

  1. Macro files have the .cs file extension. If you received the macro in a ZIP archive, be sure to extract it from the ZIP first.
  2. Start Citavi and open the project you want to work on.
  3. Important Back up the project before running a macro on it (File>Create backup > Creating a backup). Creating a backup is very important because the changes made by a macro cannot be undone!
  4. Many macros apply to the current selection only, so if you want them to apply only to some references, use the filter or search features to create a selection first. (You can identify a macro that applies to the current selection because the macro’s program code will contain a command with the ending “.GetFilteredReferences()”.)
  5. Click Tools > Macro editor or press Alt+F11 to open the macro ediotr. It can take a few seconds for the macro editor to open.
  6. In the Macro Editor, on the File menu, click Open and choose the macro file (.cs) you prepared in step 1.
  7. Click Compile. No errors should appear in the lower pane of the window.
  8. Click Run to run the macro. You will be asked to confirm that you created a backup. If you haven’t, click Cancel, create the backup, and then continue.

二、合并重复题录的macro代码

2.1 下载并加载macro代码

下载地址: https://github.com/istvank/Citavi-Macros/blob/master/merge-duplicates.cs
打开macro editor操作面板并加载下载的.cs文件
在这里插入图片描述

Citavi的宏其实类似于一个临时插件,用一次加载一次。

2.2 显示重复题录并合并

在这里插入图片描述

然后选中两个重复的题录(目前的macro代码只支持两个合并),点击 run(在上一步的时候已经点过 Compile),即可合并。
在这里插入图片描述

2.3 合并的规则

  • 对于Reference面板中的内容,如果遇到不一样的信息,则把两个信息合并,用 // 分开。一个有另一个没有的则取并集。
  • 对于划分的category和group也不会丢弃信息,而是取并集。
  • 但对于其他部分的内容,比如Evaluation和Abstract,则只保留一个。(应该是保留列表中靠前的一个)
  • 附件的话会把附件都放进来,不会删除某个附件。
  • 笔记的话内容都会保留,但排序靠后的题录的笔记会损失和pdf文件的超链接。

2.4 其他

重启Citavi后,之前加载的macro代码会清空失效。

附:macro代码

如不方便下载,可自己建立一个 .cs 代码文件。

// Copyright 2018 István Koren
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using System;
using System.Linq;
using System.ComponentModel;
using System.Collections.Generic;
using System.Windows.Forms;

using SwissAcademic.Citavi;
using SwissAcademic.Citavi.Metadata;
using SwissAcademic.Citavi.Shell;
using SwissAcademic.Collections;

// Implementation of macro editor is preliminary and experimental.
// The Citavi object model is subject to change in future version.

public static class CitaviMacro
{
    public static void Main()
    {

        //if this macro should ALWAYS affect all titles in active project, choose first option
        //if this macro should affect just filtered rows if there is a filter applied and ALL if not, choose second option
        
        //ProjectReferenceCollection references = Program.ActiveProjectShell.Project.References;        
        List<Reference> references = Program.ActiveProjectShell.PrimaryMainForm.GetSelectedReferences();
        
        //if we need a ref to the active project
        SwissAcademic.Citavi.Project activeProject = Program.ActiveProjectShell.Project;
        
        
        if (references.Count == 2)
        {
            if (references[0].ReferenceType == references[1].ReferenceType)
            {
                string originalTitle = references[0].Title;
                
                // CreatedOn, check which one is older and then take that CreatedOn and CreatedBy
                if (DateTime.Compare(references[0].CreatedOn, references[1].CreatedOn) > 0)
                {
                    // second reference is older
                    // CreatedOn is write-protected. We therefore switch the references...
                    Reference newer = references[0];
                    references[0] = references[1];
                    references[1] = newer;
                }
                
                // ModifiedOn is write-protected. It will be updated anyways now.
                
                // Abstract, naive approach...
                if (references[0].Abstract.Text.Trim().Length < references[1].Abstract.Text.Trim().Length)
                {
                    references[0].Abstract.Text = references[1].Abstract.Text;
                }
                
                // AccessDate, take newer one
                //TODO: accessdate would need to be parsed
                // right now, we just check if there is one, we take it, otherwise we leave it empty.
                if (references[0].AccessDate.Length < references[1].AccessDate.Length)
                {
                    references[0].AccessDate = references[1].AccessDate;
                }
                
                // Additions
                references[0].Additions = MergeOrCombine(references[0].Additions, references[1].Additions);
                
                // CitationKey, check if CitationKeyUpdateType is 0 at one reference if yes, take that one
                if ((references[0].CitationKeyUpdateType == UpdateType.Automatic) && (references[1].CitationKeyUpdateType == UpdateType.Manual))
                {
                    references[0].CitationKey = references[1].CitationKey;
                    references[0].CitationKeyUpdateType = references[1].CitationKeyUpdateType;
                }
                
                // CoverPath
                if (references[0].CoverPath.LinkedResourceType == LinkedResourceType.Empty)
                {
                    references[0].CoverPath = references[1].CoverPath;
                }
                
                // CustomFields (1-9)
                references[0].CustomField1 = MergeOrCombine(references[0].CustomField1, references[1].CustomField1);
                references[0].CustomField2 = MergeOrCombine(references[0].CustomField2, references[1].CustomField2);
                references[0].CustomField3 = MergeOrCombine(references[0].CustomField3, references[1].CustomField3);
                references[0].CustomField4 = MergeOrCombine(references[0].CustomField4, references[1].CustomField4);
                references[0].CustomField5 = MergeOrCombine(references[0].CustomField5, references[1].CustomField5);
                references[0].CustomField6 = MergeOrCombine(references[0].CustomField6, references[1].CustomField6);
                references[0].CustomField7 = MergeOrCombine(references[0].CustomField7, references[1].CustomField7);
                references[0].CustomField8 = MergeOrCombine(references[0].CustomField8, references[1].CustomField8);
                references[0].CustomField9 = MergeOrCombine(references[0].CustomField9, references[1].CustomField9);
                
                // Date (string type
                references[0].Date = MergeOrCombine(references[0].Date, references[1].Date);
                
                // Date2 (string type)
                references[0].Date2 = MergeOrCombine(references[0].Date2, references[1].Date2);
                
                // DOI
                references[0].Doi = MergeOrCombine(references[0].Doi, references[1].Doi);
                
                // Edition
                references[0].Edition = MergeOrCombine(references[0].Edition, references[1].Edition);
                
                // EndPage
                if (references[0].PageRange.ToString() == "")
                {
                    references[0].PageRange = references[1].PageRange;
                }
                
                // Evaluation, naive approach...
                if (references[0].Evaluation.Text.Trim().Length < references[1].Evaluation.Text.Trim().Length)
                {
                    references[0].Evaluation.Text = references[1].Evaluation.Text;
                }
                
                // HasLabel1 and HasLabel2
                if (references[1].HasLabel1)
                {
                    references[0].HasLabel1 = references[1].HasLabel1;
                }
                if (references[1].HasLabel2)
                {
                    references[0].HasLabel2 = references[1].HasLabel2;
                }
                
                // ISBN
                references[0].Isbn = MergeOrCombine(references[0].Isbn.ToString(), references[1].Isbn.ToString());
                
                // Language
                references[0].Language = MergeOrCombine(references[0].Language, references[1].Language);
                
                // Notes
                references[0].Notes = MergeOrCombine(references[0].Notes, references[1].Notes);
                
                // Number
                references[0].Number = MergeOrCombine(references[0].Number, references[1].Number);
                
                // NumberOfVolumes
                references[0].NumberOfVolumes = MergeOrCombine(references[0].NumberOfVolumes, references[1].NumberOfVolumes);
                
                // OnlineAddress
                references[0].OnlineAddress = MergeOrCombine(references[0].OnlineAddress, references[1].OnlineAddress);
                
                // OriginalCheckedBy
                references[0].OriginalCheckedBy = MergeOrCombine(references[0].OriginalCheckedBy, references[1].OriginalCheckedBy);
                
                // OriginalPublication
                references[0].OriginalPublication = MergeOrCombine(references[0].OriginalPublication, references[1].OriginalPublication);
                
                // PageCount (text)
                //TODO: apparently it is a calculated field
                // PageCountNumeralSystem (int=0)
                //TODO: apparently it is a calculated field
                // PageRangeNumberingType (int=0)
                //TODO: apparently it is a calculated field
                // PageRangeNumeralSystem (int=0)
                //TODO: apparently it is a calculated field
                
                // ParallelTitle
                references[0].ParallelTitle = MergeOrCombine(references[0].ParallelTitle, references[1].ParallelTitle);

                // PeriodicalID, naive approach...
                if ((references[0].Periodical == null) || (((references[0].Periodical != null) && (references[1].Periodical != null)) && (references[0].Periodical.ToString().Length < references[1].Periodical.ToString().Length)))
                {
                    references[0].Periodical = references[1].Periodical;
                }
                
                // PlaceOfPublication
                references[0].PlaceOfPublication = MergeOrCombine(references[0].PlaceOfPublication, references[1].PlaceOfPublication);
                
                // Price
                references[0].Price = MergeOrCombine(references[0].Price, references[1].Price);
                
                // PubMedID
                references[0].PubMedId = MergeOrCombine(references[0].PubMedId, references[1].PubMedId);
                
                // Rating (take average)
                references[0].Rating = (short) Math.Floor((decimal) ((references[0].Rating + references[1].Rating) / 2));
                
                // (!) ReferenceType (not supported)
                
                // SequenceNumber (take the one of first, as second reference will be deleted)
                
                // ShortTitle, check if ShortTitleUpdateType is 0 at one reference if yes, take that one
                if ((references[0].ShortTitleUpdateType == UpdateType.Automatic) && (references[1].ShortTitleUpdateType == UpdateType.Manual))
                {
                    references[0].ShortTitle = references[1].ShortTitle;
                }
                else if ((references[0].ShortTitleUpdateType == UpdateType.Manual) && (references[1].ShortTitleUpdateType == UpdateType.Manual))
                {
                    references[0].ShortTitle = MergeOrCombine(references[0].ShortTitle, references[1].ShortTitle);
                }
                
                // SourceOfBibliographicInformation
                references[0].SourceOfBibliographicInformation = MergeOrCombine(references[0].SourceOfBibliographicInformation, references[1].SourceOfBibliographicInformation);
                
                // SpecificFields (1-7)
                references[0].SpecificField1 = MergeOrCombine(references[0].SpecificField1, references[1].SpecificField1);
                references[0].SpecificField2 = MergeOrCombine(references[0].SpecificField2, references[1].SpecificField2);
                references[0].SpecificField3 = MergeOrCombine(references[0].SpecificField3, references[1].SpecificField3);
                references[0].SpecificField4 = MergeOrCombine(references[0].SpecificField4, references[1].SpecificField4);
                references[0].SpecificField5 = MergeOrCombine(references[0].SpecificField5, references[1].SpecificField5);
                references[0].SpecificField6 = MergeOrCombine(references[0].SpecificField6, references[1].SpecificField6);
                references[0].SpecificField7 = MergeOrCombine(references[0].SpecificField7, references[1].SpecificField7);
                
                // StartPage
                //TODO: see page range
                
                // StorageMedium
                references[0].StorageMedium = MergeOrCombine(references[0].StorageMedium, references[1].StorageMedium);
                
                // Subtitle
                references[0].Subtitle = MergeOrCombine(references[0].Subtitle, references[1].Subtitle);
                
                // SubtitleTagged
                //TODO: we are not merging SubtitleTagged as that changes the Subtitle as well
                //references[0].SubtitleTagged = MergeOrCombine(references[0].SubtitleTagged, references[1].SubtitleTagged);
                
                // TableOfContents, naive approach...                
                if ((references[0].TableOfContents == null) || (((references[0].TableOfContents != null) && (references[1].TableOfContents != null)) && (references[0].TableOfContents.ToString().Length < references[1].TableOfContents.ToString().Length)))
                {
                    references[0].TableOfContents.Text = references[1].TableOfContents.Text;
                }
                
                // TextLinks
                references[0].TextLinks = MergeOrCombine(references[0].TextLinks, references[1].TextLinks);
                
                // Title
                references[0].Title = MergeOrCombine(references[0].Title, references[1].Title);
                
                // TitleTagged
                //TODO: we are not merging TitleTagged as that changes the Title as well
                //references[0].TitleTagged = MergeOrCombine(references[0].TitleTagged, references[1].TitleTagged);
                
                // TitleInOtherLanguages
                references[0].TitleInOtherLanguages = MergeOrCombine(references[0].TitleInOtherLanguages, references[1].TitleInOtherLanguages);
                
                // TitleSupplement
                references[0].TitleSupplement = MergeOrCombine(references[0].TitleSupplement, references[1].TitleSupplement);
                
                // TitleSupplementTagged
                //TODO: we are not merging TitleSupplementTagged as that changes the TitleSupplement as well
                //references[0].TitleSupplementTagged = MergeOrCombine(references[0].TitleSupplementTagged, references[1].TitleSupplementTagged);
                
                // TranslatedTitle
                references[0].TranslatedTitle = MergeOrCombine(references[0].TranslatedTitle, references[1].TranslatedTitle);
                
                // UniformTitle
                references[0].UniformTitle = MergeOrCombine(references[0].UniformTitle, references[1].UniformTitle);
                
                // Volume
                references[0].Volume = MergeOrCombine(references[0].Volume, references[1].Volume);
                
                // Year
                references[0].Year = MergeOrCombine(references[0].Year, references[1].Year);
                
                // ReservedData
                //TODO: apparently cannot be set
                
                // RecordVersion (?)
                //TODO: apparently cannot be set
                
                
                // FOREIGN KEY fields
                
                // Locations
                foreach(Location location in references[1].Locations)
                {
                    if (!references[0].Locations.Contains(location))
                    {
                        references[0].Locations.Add(location);
                    }
                }
                
                // Groups
                references[0].Groups.AddRange(references[1].Groups);
                
                // Quotations
                references[0].Quotations.AddRange(references[1].Quotations);
                
                // ReferenceAuthors
                //references[0].Authors.AddRange(references[1].Authors);
                foreach (Person author in references[1].Authors)
                {
                    if (!references[0].Authors.Contains(author))
                    {
                        references[0].Authors.Add(author);
                    }
                }
                
                // ReferenceCategory
                references[0].Categories.AddRange(references[1].Categories);
                
                // ReferenceCollaborator
                foreach (Person collaborator in references[1].Collaborators)
                {
                    if (!references[0].Collaborators.Contains(collaborator))
                    {
                        references[0].Collaborators.Add(collaborator);
                    }
                }
                
                // ReferenceEditor
                foreach (Person editor in references[1].Editors)
                {
                    if (!references[0].Editors.Contains(editor))
                    {
                        references[0].Editors.Add(editor);
                    }
                }
                
                // ReferenceKeyword
                foreach (Keyword keyword in references[1].Keywords)
                {
                    if (!references[0].Keywords.Contains(keyword))
                    {
                        references[0].Keywords.Add(keyword);
                    }
                }
                
                // ReferenceOrganization
                foreach (Person organization in references[1].Organizations)
                {
                    if (!references[0].Organizations.Contains(organization))
                    {
                        references[0].Organizations.Add(organization);
                    }
                }
                
                // ReferenceOthersInvolved
                foreach (Person otherinvolved in references[1].OthersInvolved)
                {
                    if (!references[0].OthersInvolved.Contains(otherinvolved))
                    {
                        references[0].OthersInvolved.Add(otherinvolved);
                    }
                }
                
                // ReferencePublisher
                foreach (Publisher publisher in references[1].Publishers)
                {
                    if (!references[0].Publishers.Contains(publisher))
                    {
                        references[0].Publishers.Add(publisher);
                    }
                }
                
                // ReferenceReference
                // adding ChildReferences does not work
                //references[0].ChildReferences.AddRange(references[1].ChildReferences);
                Reference[] childReferences = references[1].ChildReferences.ToArray();
                foreach (Reference child in childReferences)
                {
                    child.ParentReference = references[0];
                }
                
                // SeriesTitle, naive approach
                if ((references[0].SeriesTitle == null) || (((references[0].SeriesTitle != null) && (references[1].SeriesTitle != null)) && (references[0].SeriesTitle.ToString().Length < references[1].SeriesTitle.ToString().Length)))
                {
                    references[0].SeriesTitle = references[1].SeriesTitle;
                }
                
                
                // change crossreferences
                foreach (EntityLink entityLink in references[1].EntityLinks)
                 {
                    if (entityLink.Source == references[1])
                    {
                        entityLink.Source = references[0];
                    }
                    else if (entityLink.Target == references[1])
                    {
                        entityLink.Target = references[0];
                    }
                }
                
                
                // write Note that the reference has been merged
                if (references[0].Notes.Trim().Length > 0)
                {
                    references[0].Notes += " |";
                }
                references[0].Notes += " This reference has been merged with a duplicate by CitaviBot.";
                
                // DONE! remove second reference
                activeProject.References.Remove(references[1]);

            }
            else
            {
                MessageBox.Show("Currently this script only supports merging two references of the same type. Please convert and try again.");
            }
        }
        else
        {
            MessageBox.Show("Currently this script only supports merging two references. Please select two and try again.");
        }
        
    }
    
    private static string MergeOrCombine(string first, string second) {
        first = first.Trim();
        second = second.Trim();
        
        // do not compare ignore case, otherwise we might lose capitalization information; in that case we rely on manual edits after the merge
        if (String.Compare(first, second, false) == 0)
        {
            // easy case, they are the same!
            return first;
        }
        else if (first.Length == 0)
        {
            return second;
        }
        else if (second.Length == 0)
        {
            return first;
        }
        else
        {
            return first + " // " + second;
        }
    }    
}
标题基于SpringBoot的马术俱乐部管理系统设计与实现AI更换标题第1章引言介绍马术俱乐部管理系统的研究背景、意义、国内外研究现状、论文方法及创新点。1.1研究背景与意义阐述马术俱乐部管理系统对提升俱乐部管理效率的重要性。1.2国内外研究现状分析国内外马术俱乐部管理系统的发展现状及存在的问题。1.3研究方法以及创新点概述本文采用的研究方法,包括SpringBoot框架的应用,以及系统的创新点。第2章相关理论总结和评述与马术俱乐部管理系统相关的现有理论。2.1SpringBoot框架理论介绍SpringBoot框架的基本原理、特点及其在Web开发中的应用。2.2数据库设计理论阐述数据库设计的基本原则、方法以及在管理系统中的应用。2.3马术俱乐部管理理论概述马术俱乐部管理的基本理论,包括会员管理、课程安排等。第3章系统设计详细描述马术俱乐部管理系统的设计方案,包括架构设计、功能模块设计等。3.1系统架构设计给出系统的整体架构,包括前端、后端和数据库的交互方式。3.2功能模块设计详细介绍系统的各个功能模块,如会员管理、课程管理、预约管理等。3.3数据库设计阐述数据库的设计方案,包括表结构、字段设计以及数据关系。第4章系统实现介绍马术俱乐部管理系统的实现过程,包括开发环境、编码实现等。4.1开发环境搭建介绍系统开发所需的环境,包括操作系统、开发工具等。4.2编码实现详细介绍系统各个功能模块的编码实现过程。4.3系统测试与调试阐述系统的测试方法、测试用例以及调试过程。第5章系统应用与分析呈现马术俱乐部管理系统的应用效果,并进行性能分析。5.1系统应用情况介绍系统在马术俱乐部中的实际应用情况。5.2系统性能分析从响应时间、并发处理能力等方面对系统性能进行分析。5.3用户反馈与改进收集用户反馈,提出系统改进建议。第6章结论与展望总结马术俱乐部管理系统的设计与实现成果,并展望未来的研究
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值