在线求一个大佬帮我看看哪里错了我又没有乱导项目我都是照着人家的慢慢敲的

博客展示了一段Android项目的build代码,随后出现报错信息,错误类型为‘Program type already present: android.support.v4.app.BackStackRecordOp’,并给出了详细的报错堆栈信息,博主寻求解决该问题的办法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

apply plugin: ‘com.android.application’

android {
compileSdkVersion 28
defaultConfig {
applicationId “com.example.asus.seeker”
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName “1.0”
testInstrumentationRunner “android.support.test.runner.AndroidJUnitRunner”
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro
}
}
sourceSets {
main {
jniLibs.srcDir ‘libs’
}
}
}

dependencies {
implementation fileTree(include: [’*.jar’], dir: ‘libs’)
implementation ‘com.android.support:appcompat-v7:28.0.0’
implementation ‘com.android.support.constraint:constraint-layout:1.1.3’
implementation ‘com.hjm:BottomTabBar:1.1.3’
testImplementation ‘junit:junit:4.12’
androidTestImplementation ‘com.android.support.test?1.0.2’
androidTestImplementation ‘com.android.support.test.espresso:espresso-core:3.0.2’
implementation files(‘libs/BaiduLBS_Android.jar’)
implementation files(‘libs/component_common_sdk_1.0.0.jar’)
implementation files(‘libs/IndoorscapeAlbumPlugin.jar’)
implementation files(‘libs/android-async-http-1.4.8.jar’)
implementation files(‘libs/android-support-v4.jar’)
implementation files(‘libs/org.apache.http.legacy.jar’)
}
这是build。
然后下面是报错代码
Error: Program type already present: android.support.v4.app.BackStackRecord O p 这 是 最 开 始 的 。 然 后 点 进 去 o r g . g r a d l e . a p i . t a s k s . T a s k E x e c u t i o n E x c e p t i o n : E x e c u t i o n f a i l e d f o r t a s k ′ : a p p : t r a n s f o r m D e x A r c h i v e W i t h E x t e r n a l L i b s D e x M e r g e r F o r D e b u g ′ . a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . E x e c u t e A c t i o n s T a s k E x e c u t e r . e x e c u t e A c t i o n s ( E x e c u t e A c t i o n s T a s k E x e c u t e r . j a v a : 103 ) a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . E x e c u t e A c t i o n s T a s k E x e c u t e r . e x e c u t e ( E x e c u t e A c t i o n s T a s k E x e c u t e r . j a v a : 73 ) a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . O u t p u t D i r e c t o r y C r e a t i n g T a s k E x e c u t e r . e x e c u t e ( O u t p u t D i r e c t o r y C r e a t i n g T a s k E x e c u t e r . j a v a : 51 ) a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . S k i p U p T o D a t e T a s k E x e c u t e r . e x e c u t e ( S k i p U p T o D a t e T a s k E x e c u t e r . j a v a : 59 ) a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . R e s o l v e T a s k O u t p u t C a c h i n g S t a t e E x e c u t e r . e x e c u t e ( R e s o l v e T a s k O u t p u t C a c h i n g S t a t e E x e c u t e r . j a v a : 54 ) a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . V a l i d a t i n g T a s k E x e c u t e r . e x e c u t e ( V a l i d a t i n g T a s k E x e c u t e r . j a v a : 59 ) a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . S k i p E m p t y S o u r c e F i l e s T a s k E x e c u t e r . e x e c u t e ( S k i p E m p t y S o u r c e F i l e s T a s k E x e c u t e r . j a v a : 101 ) a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . F i n a l i z e I n p u t F i l e P r o p e r t i e s T a s k E x e c u t e r . e x e c u t e ( F i n a l i z e I n p u t F i l e P r o p e r t i e s T a s k E x e c u t e r . j a v a : 44 ) a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . C l e a n u p S t a l e O u t p u t s E x e c u t e r . e x e c u t e ( C l e a n u p S t a l e O u t p u t s E x e c u t e r . j a v a : 91 ) a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . R e s o l v e T a s k A r t i f a c t S t a t e T a s k E x e c u t e r . e x e c u t e ( R e s o l v e T a s k A r t i f a c t S t a t e T a s k E x e c u t e r . j a v a : 62 ) a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . S k i p T a s k W i t h N o A c t i o n s E x e c u t e r . e x e c u t e ( S k i p T a s k W i t h N o A c t i o n s E x e c u t e r . j a v a : 59 ) a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . S k i p O n l y I f T a s k E x e c u t e r . e x e c u t e ( S k i p O n l y I f T a s k E x e c u t e r . j a v a : 54 ) a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . E x e c u t e A t M o s t O n c e T a s k E x e c u t e r . e x e c u t e ( E x e c u t e A t M o s t O n c e T a s k E x e c u t e r . j a v a : 43 ) a t o r g . g r a d l e . a p i . i n t e r n a l . t a s k s . e x e c u t i o n . C a t c h E x c e p t i o n T a s k E x e c u t e r . e x e c u t e ( C a t c h E x c e p t i o n T a s k E x e c u t e r . j a v a : 34 ) a t o r g . g r a d l e . e x e c u t i o n . t a s k g r a p h . D e f a u l t T a s k G r a p h E x e c u t e r Op 这是最开始的。然后点进去 org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'. at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:103) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:73) at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51) at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:59) at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54) at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:59) at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:101) at org.gradle.api.internal.tasks.execution.FinalizeInputFilePropertiesTaskExecuter.execute(FinalizeInputFilePropertiesTaskExecuter.java:44) at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:91) at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:62) at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:59) at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54) at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43) at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34) at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter Oporg.gradle.api.tasks.TaskExecutionException:Executionfailedfortask:app:transformDexArchiveWithExternalLibsDexMergerForDebug.atorg.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:103)atorg.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:73)atorg.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)atorg.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:59)atorg.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)atorg.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:59)atorg.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:101)atorg.gradle.api.internal.tasks.execution.FinalizeInputFilePropertiesTaskExecuter.execute(FinalizeInputFilePropertiesTaskExecuter.java:44)atorg.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:91)atorg.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:62)atorg.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:59)atorg.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)atorg.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)atorg.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)atorg.gradle.execution.taskgraph.DefaultTaskGraphExecuterEventFiringTaskWorker 1. r u n ( D e f a u l t T a s k G r a p h E x e c u t e r . j a v a : 256 ) a t o r g . g r a d l e . i n t e r n a l . p r o g r e s s . D e f a u l t B u i l d O p e r a t i o n E x e c u t o r 1.run(DefaultTaskGraphExecuter.java:256) at org.gradle.internal.progress.DefaultBuildOperationExecutor 1.run(DefaultTaskGraphExecuter.java:256)atorg.gradle.internal.progress.DefaultBuildOperationExecutorRunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
at org.gradle.internal.progress.DefaultBuildOperationExecutor R u n n a b l e B u i l d O p e r a t i o n W o r k e r . e x e c u t e ( D e f a u l t B u i l d O p e r a t i o n E x e c u t o r . j a v a : 328 ) a t o r g . g r a d l e . i n t e r n a l . p r o g r e s s . D e f a u l t B u i l d O p e r a t i o n E x e c u t o r . e x e c u t e ( D e f a u l t B u i l d O p e r a t i o n E x e c u t o r . j a v a : 199 ) a t o r g . g r a d l e . i n t e r n a l . p r o g r e s s . D e f a u l t B u i l d O p e r a t i o n E x e c u t o r . r u n ( D e f a u l t B u i l d O p e r a t i o n E x e c u t o r . j a v a : 110 ) a t o r g . g r a d l e . e x e c u t i o n . t a s k g r a p h . D e f a u l t T a s k G r a p h E x e c u t e r RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328) at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199) at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110) at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)atorg.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)atorg.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)atorg.gradle.execution.taskgraph.DefaultTaskGraphExecuterEventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:249)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter E v e n t F i r i n g T a s k W o r k e r . e x e c u t e ( D e f a u l t T a s k G r a p h E x e c u t e r . j a v a : 238 ) a t o r g . g r a d l e . e x e c u t i o n . t a s k g r a p h . D e f a u l t T a s k P l a n E x e c u t o r EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:238) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:238)atorg.gradle.execution.taskgraph.DefaultTaskPlanExecutorTaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:123)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access 200 ( D e f a u l t T a s k P l a n E x e c u t o r . j a v a : 79 ) a t o r g . g r a d l e . e x e c u t i o n . t a s k g r a p h . D e f a u l t T a s k P l a n E x e c u t o r 200(DefaultTaskPlanExecutor.java:79) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor 200(DefaultTaskPlanExecutor.java:79)atorg.gradle.execution.taskgraph.DefaultTaskPlanExecutorTaskExecutorWorker 1. e x e c u t e ( D e f a u l t T a s k P l a n E x e c u t o r . j a v a : 104 ) a t o r g . g r a d l e . e x e c u t i o n . t a s k g r a p h . D e f a u l t T a s k P l a n E x e c u t o r 1.execute(DefaultTaskPlanExecutor.java:104) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor 1.execute(DefaultTaskPlanExecutor.java:104)atorg.gradle.execution.taskgraph.DefaultTaskPlanExecutorTaskExecutorWorker 1. e x e c u t e ( D e f a u l t T a s k P l a n E x e c u t o r . j a v a : 98 ) a t o r g . g r a d l e . e x e c u t i o n . t a s k g r a p h . D e f a u l t T a s k E x e c u t i o n P l a n . e x e c u t e ( D e f a u l t T a s k E x e c u t i o n P l a n . j a v a : 663 ) a t o r g . g r a d l e . e x e c u t i o n . t a s k g r a p h . D e f a u l t T a s k E x e c u t i o n P l a n . e x e c u t e W i t h T a s k ( D e f a u l t T a s k E x e c u t i o n P l a n . j a v a : 597 ) a t o r g . g r a d l e . e x e c u t i o n . t a s k g r a p h . D e f a u l t T a s k P l a n E x e c u t o r 1.execute(DefaultTaskPlanExecutor.java:98) at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:663) at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:597) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor 1.execute(DefaultTaskPlanExecutor.java:98)atorg.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:663)atorg.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:597)atorg.gradle.execution.taskgraph.DefaultTaskPlanExecutorTaskExecutorWorker.run(DefaultTaskPlanExecutor.java:98)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl 1. r u n ( M a n a g e d E x e c u t o r I m p l . j a v a : 46 ) a t j a v a . u t i l . c o n c u r r e n t . T h r e a d P o o l E x e c u t o r . r u n W o r k e r ( T h r e a d P o o l E x e c u t o r . j a v a : 1142 ) a t j a v a . u t i l . c o n c u r r e n t . T h r e a d P o o l E x e c u t o r 1.run(ManagedExecutorImpl.java:46) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor 1.run(ManagedExecutorImpl.java:46)atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)atjava.util.concurrent.ThreadPoolExecutorWorker.run(ThreadPoolExecutor.java:617)
at org.gradle.internal.concurrent.ThreadFactoryImplKaTeX parse error: Expected 'EOF', got '\Seeker' at position 225: …ex archives: D:\̲S̲e̲e̲k̲e̲r̲\app\build\inte…Op
at com.android.builder.profile.Recorder$Block.handleException(Recorder.java:55)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:104)
at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:230)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
at org.gradle.api.internal.project.taskfactory.IncrementalTaskAction.doExecute(IncrementalTaskAction.java:50)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter 1. r u n ( E x e c u t e A c t i o n s T a s k E x e c u t e r . j a v a : 124 ) a t o r g . g r a d l e . i n t e r n a l . p r o g r e s s . D e f a u l t B u i l d O p e r a t i o n E x e c u t o r 1.run(ExecuteActionsTaskExecuter.java:124) at org.gradle.internal.progress.DefaultBuildOperationExecutor 1.run(ExecuteActionsTaskExecuter.java:124)atorg.gradle.internal.progress.DefaultBuildOperationExecutorRunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
at org.gradle.internal.progress.DefaultBuildOperationExecutorKaTeX parse error: Expected 'EOF', got '\Seeker' at position 654: …ex archives: D:\̲S̲e̲e̲k̲e̲r̲\app\build\inte…Op
at com.android.builder.dexing.D8DexArchiveMerger.getExceptionToRethrow(D8DexArchiveMerger.java:132)
at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:117)
at com.android.build.gradle.internal.transforms.DexMergerTransformCallable.call(DexMergerTransformCallable.java:101)
at com.android.build.gradle.internal.transforms.ExternalLibsMergerTransform.transform(ExternalLibsMergerTransform.kt:122)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:239)
at com.android.build.gradle.internal.pipeline.TransformTask 2. c a l l ( T r a n s f o r m T a s k . j a v a : 235 ) a t c o m . a n d r o i d . b u i l d e r . p r o f i l e . T h r e a d R e c o r d e r . r e c o r d ( T h r e a d R e c o r d e r . j a v a : 102 ) . . . 49 m o r e C a u s e d b y : c o m . a n d r o i d . t o o l s . r 8. C o m p i l a t i o n F a i l e d E x c e p t i o n : C o m p i l a t i o n f a i l e d t o c o m p l e t e a t c o m . a n d r o i d . t o o l s . r 8. u t i l s . E x c e p t i o n U t i l s . w i t h C o m p i l a t i o n H a n d l e r ( E x c e p t i o n U t i l s . j a v a : 65 ) a t c o m . a n d r o i d . t o o l s . r 8. u t i l s . E x c e p t i o n U t i l s . w i t h D 8 C o m p i l a t i o n H a n d l e r ( E x c e p t i o n U t i l s . j a v a : 43 ) a t c o m . a n d r o i d . t o o l s . r 8. D 8. r u n ( D 8. j a v a : 90 ) a t c o m . a n d r o i d . b u i l d e r . d e x i n g . D 8 D e x A r c h i v e M e r g e r . m e r g e D e x A r c h i v e s ( D 8 D e x A r c h i v e M e r g e r . j a v a : 115 ) . . . 54 m o r e C a u s e d b y : c o m . a n d r o i d . t o o l s . r 8. u t i l s . A b o r t E x c e p t i o n : E r r o r : P r o g r a m t y p e a l r e a d y p r e s e n t : a n d r o i d . s u p p o r t . v 4. a p p . B a c k S t a c k R e c o r d 2.call(TransformTask.java:235) at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:102) ... 49 more Caused by: com.android.tools.r8.CompilationFailedException: Compilation failed to complete at com.android.tools.r8.utils.ExceptionUtils.withCompilationHandler(ExceptionUtils.java:65) at com.android.tools.r8.utils.ExceptionUtils.withD8CompilationHandler(ExceptionUtils.java:43) at com.android.tools.r8.D8.run(D8.java:90) at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:115) ... 54 more Caused by: com.android.tools.r8.utils.AbortException: Error: Program type already present: android.support.v4.app.BackStackRecord 2.call(TransformTask.java:235)atcom.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:102)...49moreCausedby:com.android.tools.r8.CompilationFailedException:Compilationfailedtocompleteatcom.android.tools.r8.utils.ExceptionUtils.withCompilationHandler(ExceptionUtils.java:65)atcom.android.tools.r8.utils.ExceptionUtils.withD8CompilationHandler(ExceptionUtils.java:43)atcom.android.tools.r8.D8.run(D8.java:90)atcom.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:115)...54moreCausedby:com.android.tools.r8.utils.AbortException:Error:Programtypealreadypresent:android.support.v4.app.BackStackRecordOp
at com.android.tools.r8.utils.Reporter.failIfPendingErrors(Reporter.java:116)
at com.android.tools.r8.utils.Reporter.fatalError(Reporter.java:74)
at com.android.tools.r8.utils.ExceptionUtils.withCompilationHandler(ExceptionUtils.java:59)
… 57 more

救命呀

<think>我们计划开发一个Excel插件,用于解决三维装箱问题。用户可以在Excel中输入货物和容器的数据,然后运行插件进行装箱计算,并生成装箱方案报告。我们将使用VBA编写,因为它是Excel插件开发的常用语言。功能概述:1.用户输入:-容器数据:在名为"ContainerConfig"的工作表中输入容器的名称、长度、宽度、高度、最大承重和成本。-货物数据:在名为"CargoData"的工作表中输入货物的ID、长度、宽度、高度、重量、数量、是否可以旋转、是否易碎。2.装箱算法:-采用贪心算法,结合最佳适应策略。-支持货物旋转(6个方向)。-考虑货物易碎性(易碎货物必须放在顶部)和重量限制。3.输出结果:-生成一个新的工作簿,包含三个工作表:a.摘要报告:显示每个类型容器的使用数量、体积利用率和重量利用率。b.详细报告:每个容器的装箱详情,包括货物ID、位置、旋转状态等。c.可视化报告:用Excel单元格着色模拟每个容器的装箱布局。4.用户交互:-提供一个按钮或菜单来运行插件。-计算完成后,允许用户保存结果工作簿。步骤:步骤1:设计数据结构步骤2:实现数据加载步骤3:实现排序算法(按体积和易碎性)步骤4:实现装箱算法步骤5:生成报告步骤6:添加用户界面和误处理由于代码较长,我们将分模块实现。以下是完整的VBA代码:注意:在Excel中打开VBA编辑器(Alt+F11),插入一个模块,将以下代码粘贴进去。使用说明:1.在Excel工作簿中创建两个工作表,分别命名为"ContainerConfig"和"CargoData",并按照以下格式输入数据:-ContainerConfig表:列顺序为[名称,长度(m),宽度(m),高度(m),最大承重(kg),成本]- CargoData表:列顺序为[ID,长度(cm),宽度(cm),高度(cm),重量(kg),数量,可旋转(yes/no),易碎(yes/no)]2.运行宏"RunContainerPacking"3.插件将生成装箱结果,并询问保存位置。以下是完整代码:</think># Excel货柜装箱优化插件 我将为您开发一个完整的Excel货柜装箱优化插件,采用VBA实现三维装箱算法,并提供直观的用户界面。 ## 完整解决方案 ```vba ' 模块: ContainerPacking Option Explicit ' --- 数据结构定义 --- Private Type CargoItem ID As String Length As Double Width As Double Height As Double Weight As Double Quantity As Integer CanRotate As Boolean IsFragile As Boolean Color As Long End Type Private Type Container Name As String Length As Double Width As Double Height As Double MaxWeight As Double Cost As Double End Type Private Type PackedItem CargoID As String PositionX As Double PositionY As Double PositionZ As Double Rotated As Boolean RotationType As String End Type Private Type PackedBin Container As Container Items() As PackedItem UsedVolume As Double UsedWeight As Double End Type ' --- 全局变量 --- Private AllCargos() As CargoItem Private AllContainers() As Container Private PackingResults() As PackedBin Private TempWorkbook As Workbook ' --- 主过程 --- Public Sub RunContainerPacking() On Error GoTo ErrorHandler Application.ScreenUpdating = False Application.DisplayAlerts = False ' 检查权限 If Not CheckPermissions() Then MsgBox "Required permissions not available", vbCritical Exit Sub End If ' 初始化数据 If Not InitializeData() Then MsgBox "Data initialization failed", vbCritical Exit Sub End If ' 执行装箱 If Not PerformPacking() Then MsgBox "Packing calculation failed", vbCritical Exit Sub End If ' 生成报告 If Not GenerateReport() Then Msg极 "Report generation failed", vbCritical Exit Sub End If ' 提供保存选项 Dim savePath As String savePath = Application.GetSaveAsFilename( _ InitialFileName:="ContainerPackingReport_" & Format(Now, "yyyymmdd_hhmm") & ".xlsx", _ FileFilter:="Excel Files (*.xlsx), *.xlsx") If savePath <> "False" Then On Error Resume Next TempWorkbook.SaveAs savePath If Err.Number <> 0 Then MsgBox "Error saving file: " & Err.Description, vbCritical Else MsgBox "Report saved to: " & vbCrLf & savePath, vbInformation, "Complete" End If On Error GoTo 0 Else MsgBox "Report generated but not saved", vbExclamation End If Cleanup: ' 清理资源 If Not TempWorkbook Is Nothing Then On Error Resume Next TempWorkbook.Close False Set TempWorkbook = Nothing On Error GoTo 0 End If Application.DisplayAlerts = True Application.ScreenUpdating = True Exit Sub ErrorHandler: MsgBox "Runtime error: " & Err.Description & vbCrLf & _ "Error number: " & Err.Number, vbCritical Resume Cleanup End Sub ' --- 检查权限 --- Private Function CheckPermissions() As Boolean On Error Resume Next ' 通过创建形状测试权限 Dim ws As Worksheet Set ws = ThisWorkbook.Worksheets.Add Dim testShape As Shape Set testShape = ws.Shapes.AddShape(msoShapeRectangle, 0, 0, 10, 10) If Err.Number <> 0 Then CheckPermissions = False Else testShape.Delete ws.Delete CheckPermissions = True End If On Error GoTo 0 End Function ' --- 初始化数据 --- Private Function InitializeData() As Boolean On Error GoTo ErrorHandler ' 1. 加载容器数据 Dim ws As Worksheet On Error Resume Next Set ws = ThisWorkbook.Sheets("ContainerConfig") On Error GoTo ErrorHandler If ws Is Nothing Then MsgBox "Sheet 'ContainerConfig' not found", vbCritical Exit Function End If Dim lastRow As Long lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row If lastRow < 2 Then MsgBox "No data in container config", vbExclamation Exit Function End If ReDim AllContainers(1 To lastRow - 1) Dim i As Long For i = 2 To lastRow With AllContainers(i - 1) .Name = CStr(ws.Cells(i, 1).Value) .Length = CDbl(ws.Cells(i, 2).Value) * 100 ' 转换为厘米 .Width = CDbl(ws.Cells(i, 3).Value) * 100 .Height = CDbl(ws.Cells(i, 4).Value) * 100 .MaxWeight = CDbl(极.Cells(i, 5).Value) .Cost = CDbl(ws.Cells(i, 6).Value) End With Next i ' 2. 加载货物数据 On Error Resume Next Set ws = ThisWorkbook.Sheets("CargoData") On Error GoTo ErrorHandler If ws Is Nothing Then MsgBox "Sheet 'CargoData' not found", vbCritical Exit Function End If lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row If lastRow < 2 Then MsgBox "No data in cargo sheet", vbExclamation Exit Function End If ReDim AllCargos(1 To lastRow - 1) Dim colorPalette As Variant colorPalette = Array(RGB(255, 200, 200), RGB(200, 255, 200), RGB(200, 200, 255), _ RGB(255, 255, 200), RGB(255, 200, 255), RGB(200, 255, 255)) For i = 2 To lastRow With AllCargos(i - 1) .ID = CStr(ws.Cells(i, 1).Value) .Length = CDbl(ws.Cells(i, 2).Value) .Width = CDbl(ws.Cells(i, 3).Value) .Height = CDbl(ws.Cells(i, 4).Value) .Weight = CDbl(ws.Cells(i, 5).Value) .Quantity = CInt(ws.Cells(i, 6).Value) .CanRotate = (LCase(CStr(ws.Cells(i, 7).Value)) = "yes") .IsFragile = (LCase(CStr(ws.Cells(i, 8).Value)) = "yes") .Color = colorPalette((i - 2) Mod (UBound(colorPalette) + 1)) End With Next i InitializeData = True Exit Function ErrorHandler: MsgBox "Data initialization error: " & Err.Description, vbCritical InitializeData = False End Function ' --- 装箱算法 --- Private Function PerformPacking() As Boolean On Error GoTo ErrorHandler ' 1. 按体积和易碎性排序 SortCargos ' 2. 初始化结果数组 Dim containerCount As Long containerCount = UBound(AllContainers) - LBound(AllContainers) + 1 ReDim PackingResults(1 To containerCount * 2) ' 3. 复制货物数据 Dim workingCargos() As CargoItem workingCargos = CopyCargoArray(AllCargos) ' 4. 主装箱循环 Dim binIndex As Long: binIndex = 1 Dim cargoIndex As Long Dim containerIndex As Long For containerIndex = LBound(AllContainers) To UBound(AllContainers) Dim contLength As Double, contWidth As Double, contHeight As Double, contMaxWeight As Double contLength = AllContainers(containerIndex).Length contWidth = AllContainers(containerIndex).Width contHeight = AllContainers(containerIndex).Height contMaxWeight = AllContainers(containerIndex).MaxWeight Dim remainingLength As Double: remainingLength = contLength Dim remainingWidth As Double: remainingWidth = contWidth Dim remainingHeight As Double: remainingHeight = contHeight Dim usedVolume As Double: usedVolume = 0 Dim usedWeight As Double: usedWeight = 0 Dim itemsInBin() As PackedItem Dim itemCount As Long: itemCount = 0 For cargoIndex = LBound(workingCargos) To UBound(workingCargos) If workingCargos(cargoIndex).Quantity <= 0 Then GoTo NextCargo Dim cargoLength As Double, cargoWidth As Double, cargoHeight As Double, cargoWeight As Double Dim cargoCanRotate As Boolean, cargoIsFragile As Boolean cargoLength = workingCargos(cargoIndex).Length cargoWidth = workingCargos(cargoIndex).Width cargoHeight = workingCargos(cargoIndex).Height cargoWeight = workingCargos(cargoIndex).Weight cargoCanRotate = workingCargos(cargoIndex).CanRotate cargoIsFragile = workingCargos(cargoIndex).IsFragile Dim bestPosition As Variant bestPosition = FindBestPosition(cargoLength, cargoWidth, cargoHeight, cargoWeight, _ cargoCanRotate, cargoIsFragile, _ remainingLength, remainingWidth, remainingHeight, _ contMaxWeight - usedWeight) If Not IsEmpty(bestPosition) Then itemCount = itemCount + 1 ReDim Preserve itemsInBin(1 To itemCount) With itemsInBin(itemCount) .CargoID = workingCargos(cargoIndex).ID .PositionX = bestPosition(0) .PositionY = bestPosition(1) .PositionZ = bestPosition(2) .Rotated = bestPosition(3) .RotationType = bestPosition(4) End With Dim cargoVolume As Double cargoVolume = cargoLength * cargoWidth * cargoHeight usedVolume = usedVolume + cargoVolume usedWeight = usedWeight + cargoWeight If cargoIsFragile Then remainingHeight = remainingHeight - cargoHeight Else Dim placedLength As Double, placedWidth As Double, placedHeight As Double If bestPosition(3) Then placedLength = cargoWidth placedWidth = cargoLength Else placedLength = cargoLength placedWidth = cargoWidth End If placedHeight = cargoHeight remainingLength = remainingLength - placedLength If remainingLength <= 0 Then remainingLength = contLength remainingWidth = remainingWidth - placedWidth If remainingWidth <= 0 Then remainingWidth = contWidth remainingHeight = remainingHeight - placedHeight End If End If End If workingCargos(cargoIndex).Quantity = workingCargos(cargoIndex).Quantity - 1 End If NextCargo: Next cargoIndex If itemCount > 0 Then ReDim Preserve PackingResults(1 To binIndex) Dim currentContainer As Container currentContainer = AllContainers(containerIndex) PackingResults(binIndex).Container = currentContainer PackingResults(binIndex).Items = itemsInBin PackingResults(binIndex).UsedVolume = usedVolume PackingResults(binIndex).UsedWeight = usedWeight binIndex = binIndex + 1 End If Next containerIndex If binIndex > 1 Then ReDim Preserve PackingResults(1 To binIndex - 1) End If PerformPacking = True Exit Function ErrorHandler: MsgBox "Packing error: " & Err.Description, vbCritical PerformPacking = False End Function ' --- 查找最佳位置 --- Private Function FindBestPosition(cargoLength As Double, cargoWidth As Double, cargoHeight As Double, _ cargoWeight As Double, cargoCanRotate As Boolean, cargoIsFragile As Boolean, _ containerLength As Double, containerWidth As Double, containerHeight As极, _ remainingWeight As Double) As Variant Dim tempCargo As CargoItem With tempCargo .Length = cargoLength .Width = cargoWidth .Height = cargoHeight .Weight = cargoWeight .CanRotate = cargoCanRotate .IsFragile = cargoIsFragile End With FindBestPosition = FindBestPositionOriginal(tempCargo, containerLength, containerWidth, _ containerHeight, remainingWeight) End Function ' --- 原始位置查找器 --- Private Function FindBestPositionOriginal(cargo As CargoItem, containerLength As Double, _ containerWidth As Double, containerHeight As Double, _ remainingWeight As Double) As Variant On Error Resume Next If cargo.Weight > remainingWeight Then FindBestPositionOriginal = Empty Exit Function End If Dim rotations As Variant rotations = GetRotationOptions(cargo.Length, cargo.Width, cargo.Height, cargo.CanRotate) Dim bestFit As Double: bestFit = -1 Dim bestIndex As Integer: bestIndex = -1 Dim i As Integer For i = LBound(rotations) To UBound(rotations) Dim rLength As Double, rWidth As Double, rHeight As Double rLength = rotations(i)(0) rWidth = rotations(i)(1) rHeight = rotations(i)(2) If rLength <= containerLength And rWidth <= containerWidth And rHeight <= containerHeight Then Dim fitScore As Double fitScore = (containerLength - rLength) + (containerWidth - rWidth) + (containerHeight - rHeight) If bestFit = -1 Or fitScore < bestFit Then bestFit = fitScore bestIndex = i End If End If Next i If bestIndex = -1 Then FindBestPositionOriginal = Empty Else Dim result(0 To 4) As Variant result(0) = 0 result(1) = 0 result(2) = containerHeight - rotations(bestIndex)(2) result(3) = (bestIndex > 0) result(4) = rotations(bestIndex)(3) FindBestPositionOriginal = result End If End Function ' --- 获取旋转选项 --- Private Function GetRotationOptions(length As Double, width As Double, height As Double, canRotate As Boolean) As Variant If Not canRotate Then GetRotationOptions = Array(Array(length, width, height, "Original")) Exit Function End If Dim rotations(1 To 6) As Variant rotations(1) = Array(length, width, height, "Original") rotations(2) = Array(length, height, width, "Rotated90") rotations(3) = Array(width, length, height, "Rotated90") rotations(4) = Array(width, height, length, "Rotated180") rotations(5) = Array(height, length, width, "Rotated270") rotations(6) = Array(height, width, length, "Rotated270") GetRotationOptions = rotations End Function ' --- 排序货物 --- Private Sub SortCargos() Dim i As Long, j As Long For i = LBound(AllCargos) To UBound(AllCargos) - 1 For j = i + 1 To UBound(AllCargos) Dim volumeI As Double, volumeJ As Double volumeI = AllCargos(i).Length * AllCargos(i).Width * AllCargos(i).Height volumeJ = AllCargos(j).Length * AllCargos(j).Width * AllCargos(j).Height If (volumeJ > volumeI) Or _ (volumeJ = volumeI And Not AllCargos(i).IsFragile And AllCargos(j).IsFragile) Then Dim temp As CargoItem temp = AllCargos(i) AllCargos(i) = AllCargos(j) AllCargos(j) = temp End If Next j Next i End Sub ' --- 复制货物数组 --- Private Function CopyCargoArray(source() As CargoItem) As CargoItem() Dim dest() As CargoItem ReDim dest(LBound(source) To UBound(source)) Dim i As Long For i = LBound(source) To UBound(source) dest(i) = source(i) Next i CopyCargoArray = dest End Function ' --- 生成报告 --- Private Function GenerateReport() As Boolean On Error GoTo ErrorHandler If UBound(PackingResults) - LBound(PackingResults) + 1 <= 0 Then MsgBox "No packing results available", vbCritical GenerateReport = False Exit Function End If Dim newWorkbook As Workbook On Error Resume Next Set newWorkbook = Application.Workbooks.Add If newWorkbook Is Nothing Then MsgBox "Cannot create workbook", vbCritical GenerateReport = False Exit Function End If On Error GoTo ErrorHandler Application.DisplayAlerts = False Dim i As Integer For i = newWorkbook.Worksheets.Count To 1 Step -1 On Error Resume Next Dim ws As Worksheet Set ws = newWorkbook.Worksheets(i) If Not ws Is Nothing Then If ws.ProtectContents Then ws.Unprotect "" End If ws.Cells.Clear ws.Name = "Sheet" & i End If On Error GoTo ErrorHandler Next i Set TempWorkbook = newWorkbook If Not CreateSummarySheet() Then GoTo ErrorHandler If Not CreateDetailSheet() Then GoTo ErrorHandler On Error Resume Next If Not CreateVisualizationSheet() Then MsgBox "Visualization failed", vbExclamation End If On Error GoTo ErrorHandler On Error Resume Next Dim summarySheet As Worksheet Set summarySheet = TempWorkbook.Worksheets("Summary") If Not summarySheet Is Nothing Then summarySheet.Activate End If On Error GoTo ErrorHandler GenerateReport = True Exit Function ErrorHandler: MsgBox "Report error: " & Err.Description & vbCrLf & _ "Error: " & Err.Number, vbCritical GenerateReport = False On Error Resume Next If Not newWorkbook Is Nothing Then newWorkbook.Close SaveChanges:=False End If On Error GoTo 0 End Function ' --- 创建摘要工作表 --- Private Function CreateSummarySheet() As Boolean On Error GoTo ErrorHandler Dim ws As Worksheet Set ws = TempWorkbook.Worksheets.Add ws.Name = "Summary" With ws.Range("A1:D1") .Merge .Value = "Packing Summary" .Font.Size = 16 .Font.Bold = True .HorizontalAlignment = xlCenter End With ws.Range("A3").Value = "ContainerType" ws.Range("B3").Value = "Count" ws.Range("C3").Value = "VolumeUtil" ws.Range("D3").Value = "WeightUtil" With ws.Range("A3:D3") .Font.Bold = True .Interior.Color = RGB(200, 230, 255) End With Dim containerStats As Object Set containerStats = CreateObject("Scripting.Dictionary") Dim i As Long For i = LBound(PackingResults) To UBound(PackingResults) Dim containerName As String containerName = PackingResults(i).Container.Name If Not containerStats.Exists(containerName) Then containerStats.Add containerName, Array(0, 0, 0) End If Dim stats As Variant stats = containerStats(containerName) stats(0) = stats(0) + 1 stats(1) = stats(1) + PackingResults(i).UsedVolume stats(2) = stats(2) + PackingResults(i).UsedWeight containerStats(containerName) = stats Next i Dim rowIndex As Long: rowIndex = 4 Dim key As Variant For Each key In containerStats.Keys Dim statsData As Variant statsData = containerStats(key) Dim found As Boolean: found = False Dim j As Long Dim contLength As Double, contWidth As Double, contHeight As Double, contMaxWeight As Double For j = LBound(AllContainers) To UBound(AllContainers) If AllContainers(j).Name = CStr(key) Then contLength = AllContainers(j).Length contWidth = AllContainers(j).Width contHeight = AllContainers(j).Height contMaxWeight = AllContainers(j).MaxWeight found = True Exit For End If Next j If found Then ws.Cells(rowIndex, 1).Value = key ws.Cells(rowIndex, 2).Value = statsData(0) Dim totalVolume As Double totalVolume = contLength * contWidth * contHeight ws.Cells(rowIndex, 3).Value = Format(statsData(1) / totalVolume, "0.00%") ws.Cells(rowIndex, 4).Value = Format(statsData(2) / contMaxWeight, "0.00%") rowIndex = rowIndex + 1 End If Next key ws.Cells(rowIndex, 1).Value = "Total" ws.Cells(rowIndex, 2).Value = Application.WorksheetFunction.Sum(ws.Range("B4:B" & rowIndex - 1)) With ws.Range("A" & rowIndex & ":D" & rowIndex) .Font.Bold = True .Interior.Color = RGB(255, 255, 200) End With ws.Columns("A:D").AutoFit CreateSummarySheet = True Exit Function ErrorHandler: MsgBox "Summary error: " & Err.Description, vbCritical CreateSummarySheet = False End Function ' --- 创建详细信息工作表 --- Private Function CreateDetailSheet() As Boolean On Error GoTo ErrorHandler Dim ws As Worksheet Set ws = TempWorkbook.Worksheets.Add ws.Name = "Details" With ws.Range("A1:H1") .Merge .Value = "Packing Details" .Font.Size = 16 .Font.Bold极 True .HorizontalAlignment = xlCenter End With Dim headers As Variant headers = Array("ContainerID", "ContainerType", "CargoID", "Position", "Dimensions", _ "Rotation", "Weight", "Fragile") Dim headerRange As Range Set headerRange = ws.Range("A3:H3") headerRange.Value = headers headerRange.Font.Bold = True headerRange.Interior.Color = RGB(200, 230, 255) Dim rowIndex As Long: rowIndex = 4 Dim binIndex As Long For binIndex = LBound(PackingResults) To UBound(PackingResults) Dim currentBin As PackedBin currentBin = PackingResults(binIndex) Dim itemIndex As Long For itemIndex = LBound(currentBin.Items) To UBound(currentBin.Items) Dim currentItem As PackedItem currentItem = currentBin.Items(itemIndex) Dim cargoDef As CargoItem Dim found As Boolean: found = False Dim i As Long For i = LBound(AllCargos) To UBound(AllCargos) If AllCargos(i).ID = currentItem.CargoID Then cargoDef = AllCargos(i) found = True Exit For End If Next i If found Then ws.Cells(rowIndex, 1).Value = "CT" & Format(binIndex, "000") ws.Cells(rowIndex, 2).Value = currentBin.Container.Name ws.Cells(rowIndex, 3).Value = currentItem.CargoID ws.Cells(rowIndex, 4).Value = Format(currentItem.PositionX, "0.00") & ", " & _ Format(currentItem.PositionY, "0.00") & ", " & _ Format(currentItem.PositionZ, "0.00") Dim length As Double, width As Double, height As Double If currentItem.Rotated Then length = cargoDef.Width width = cargoDef.Length Else length = cargoDef.Length width = cargoDef.Width End If height = cargoDef.Height ws.Cells(rowIndex, 5).Value = length & "x" & width & "x" & height ws.Cells(rowIndex, 6).Value = currentItem.RotationType ws.Cells(rowIndex, 7).Value = cargoDef.Weight ws.Cells(rowIndex, 8).Value = IIf(cargoDef.IsFragile, "Yes", "No") rowIndex = rowIndex + 1 End If Next itemIndex Next binIndex If rowIndex > 4 Then ws.Cells(rowIndex, 1).Value = "Summary" ws.Cells(rowIndex, 1).Font.Bold = True ws.Range(ws.Cells(rowIndex, 1), ws.Cells(rowIndex, 8)).Interior.Color = RGB(255, 255, 200) Dim prevBin As String: prevBin = "" Dim startRow As Long: startRow = 4 Dim binCount As Long: binCount = 0 Dim totalWeight As Double: totalWeight = 0 For i = 4 To rowIndex - 1 Dim currentBinID As String currentBinID = ws.Cells(i, 1).Value If currentBinID <> prevBin And i > 4 Then ws.Cells(startRow - 1, 7).Value = "Subtotal:" ws.Cells(startRow - 1, 8).Value = "Container " & prevBin ws.Range(ws.Cells(startRow - 1, 1), ws.Cells(startRow - 1, 8)).Font.Bold = True startRow = i binCount = binCount + 1 End If prevBin = currentBinID totalWeight = totalWeight + ws.Cells(i, 7).Value Next i ws.Cells(startRow - 1, 7).Value = "Subtotal:" ws.Cells(startRow - 1, 8).Value = "Container " & prevBin ws.Range(ws.Cells(startRow - 1, 1), ws.Cells(startRow - 1, 8)).Font.Bold = True ws.Cells(rowIndex, 7).Value = "Total:" ws.Cells(rowIndex, 8).Value = binCount & " containers, " & totalWeight & " kg" End If ws.Columns("A:H").AutoFit ws.Range("A3:H" & rowIndex).Borders.LineStyle = xlContinuous CreateDetailSheet = True Exit Function ErrorHandler: MsgBox "Detail error: " & Err.Description, vbCritical CreateDetailSheet = False End Function ' --- 创建可视化工作表 --- Private Function CreateVisualizationSheet() As Boolean On Error GoTo ErrorHandler If UBound(PackingResults) - LBound(PackingResults) + 1 <= 0 Then MsgBox "No data for visualization", vbExclamation CreateVisualizationSheet = True Exit Function End If Dim ws As Worksheet On Error Resume Next Dim sheetCount As Integer sheetCount = TempWorkbook.Worksheets.Count If sheetCount = 0 Then Set ws = TempWorkbook.Worksheets.Add Else Set ws = TempWorkbook.Worksheets(sheetCount) ws.Cells.Clear End If On Error Resume Next ws.Name = "Visualization" If Err.Number <> 0 Then ws.Name = "Viz_" & Format(Now, "hhmmss") End If On Error GoTo ErrorHandler With ws.Range("A1:D1") On Error Resume Next .Merge If Err.Number = 0 Then .Value = "Packing Visualization" .Font.Size = 16 .Font.Bold = True .HorizontalAlignment = xlCenter End If On Error GoTo ErrorHandler End With On Error Resume Next With ws.Range("A3:D3") .Value = "Container layout visualization (scaled)" .Font.Italic = True End With On Error GoTo ErrorHandler Dim scaleFactor As Double: scaleFactor = 0.3 If scaleFactor <= 0 Then scaleFactor = 0.1 Dim containerHeight As Double: containerHeight = 150 Dim spacing As Double: spacing = 30 Dim topPos As Double: topPos = 50 Dim binIndex As Long For binIndex = LBound(PackingResults) To UBound(PackingResults) If binIndex < LBound(PackingResults) Or binIndex > UBound(PackingResults) Then Exit For End If Dim currentBin As PackedBin On Error Resume Next currentBin = PackingResults(binIndex) On Error GoTo ErrorHandler If currentBin.Container.Length <= 0 Or currentBin.Container.Width <= 0 Then MsgBox "Invalid container size: " & currentBin.Container.Name, vbExclamation GoTo NextBin End If Dim labelRow As Long labelRow = topPos \ 15 If labelRow < 1 Then label极 = 1 On Error Resume Next ws.Cells(labelRow, 1).Value = "Container CT" & Format(binIndex, "000") & " - " & currentBin.Container.Name If Err.Number = 0 Then ws.Cells(labelRow, 1).Font.Bold = True End If On Error GoTo ErrorHandler Dim leftPos As Double: leftPos = 50 Dim containerWidth As Double: containerWidth = currentBin.Container.Length * scaleFactor Dim containerDepth As Double: containerDepth = currentBin.Container.Width * scaleFactor If containerWidth > 1000 Then containerWidth = 1000 If containerDepth > 1000 Then containerDepth = 1000 Dim containerRange As Range On Error Resume Next Set containerRange = ws.Range(ws.Cells(labelRow + 1, 2), _ ws.Cells(labelRow + 1 + containerDepth \ 15, 2 + containerWidth \ 10)) If Not containerRange Is Nothing Then With containerRange.Borders .LineStyle = xlContinuous .Weight = xlThick .Color = RGB(0, 0, 0) End With End If On Error GoTo ErrorHandler On Error Resume Next ws.Cells(labelRow, 2 + containerWidth \ 10 + 1).Value = _ Format(currentBin.Container.Length, "0") & " cm" ws.Cells(labelRow + 1 + containerDepth \ 15, 1).Value = _ Format(currentBin.Container.Width, "0") & " cm" On Error GoTo ErrorHandler Dim itemIndex As Long Dim cargoLeft As Double, cargoTop As Double Dim rowHeight As Double: rowHeight = 0 Dim currentRowWidth As Double: currentRowWidth = 0 Dim rowStartLeft As Double: rowStartLeft = leftPos If Not IsArrayInitialized(currentBin.Items) Then GoTo NextBin For itemIndex = LBound(currentBin.Items) To UBound(currentBin.Items) If itemIndex < LBound(currentBin.Items) Or itemIndex > UBound(currentBin.Items) Then Exit For End If Dim currentItem As PackedItem On Error Resume Next currentItem = currentBin.Items(itemIndex) On Error GoTo ErrorHandler Dim cargoDef As CargoItem Dim found As Boolean: found = False Dim i As Long For i = LBound(AllCargos) To UBound(AllCargos) If i < LBound(AllCargos) Or i > UBound(AllCargos) Then Exit For End If If AllCargos(i).ID = currentItem.CargoID Then cargoDef = AllCargos(i) found = True Exit For End If Next i If Not found Then GoTo NextItem Dim cargoLength As Double, cargoWidth As Double If currentItem.Rotated Then cargoLength = cargoDef.Width * scaleFactor cargoWidth = cargoDef.Length * scaleFactor Else cargoLength = cargoDef.Length * scaleFactor cargoWidth = cargoDef.Width * scaleFactor End If If cargoLength <= 0 Then cargoLength = 5 If cargoWidth <= 0 Then cargoWidth = 5 If rowStartLeft + currentRowWidth + cargoLength > leftPos + containerWidth Then cargoTop = cargoTop + rowHeight + 5 rowStartLeft = leftPos currentRowWidth = 0 rowHeight = 0 End If cargoLeft = rowStartLeft + currentRowWidth currentRowWidth = currentRowWidth + cargoLength + 5 Dim cargoRange As Range Dim startRow As Long, endRow As Long Dim startCol As Long, endCol As Long startRow = (cargoTop) \ 15 endRow = (cargoTop + cargoWidth) \ 15 startCol = (cargoLeft) \ 10 endCol = (cargoLeft + cargoLength) \ 10 If startRow < 1 Then startRow = 1 If startCol < 1 Then startCol = 1 If endRow > ws.Rows.Count Then endRow = ws.Rows.Count If endCol > ws.Columns.Count Then endCol = ws.Columns.Count On Error Resume Next Set cargoRange = ws
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值